selint-1.2.1/0000755000175100001710000000000014167117420010012 500000000000000selint-1.2.1/compile0000755000175100001710000001632714167117365011331 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: selint-1.2.1/NOTICE0000644000175100001710000000005514167117255010644 00000000000000SELint Copyright 2019 Tresys Technology, LLC selint-1.2.1/install-sh0000755000175100001710000003601014167117365011746 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # Note that $RANDOM variable is not portable (e.g. dash); Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p' feature. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: selint-1.2.1/missing0000755000175100001710000001533614167117365011351 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2018 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: selint-1.2.1/INSTALL0000755000175100001710000003661414167117255011006 00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. selint-1.2.1/src/0000755000175100001710000000000014167117420010601 500000000000000selint-1.2.1/src/fc_checks.h0000644000175100001710000001000314167117255012602 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FC_CHECKS_H #define FC_CHECKS_H #include "check_hooks.h" /********************************************* * Check for issues with file context labels type field. * Called on NODE_FC_ENTRY nodes. * node - the node to check * returns NULL if passed or check_result for issue S-002 *********************************************/ struct check_result *check_file_context_types_in_mod(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for gen_context calls that omit an mls component * Called on NODE_FC_ENTRY nodes. * node - the node to check * returns NULL if passed or check_result for issue S-007 *********************************************/ struct check_result *check_gen_context_no_range(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for potentially unescaped regex characters. * Called on NODE_FC_ENTRY nodes; * node - the node to check * returns NULL if called on a node type other than error node * or a check_result for issue W-004 *********************************************/ struct check_result *check_file_context_regex(const struct check_data *data, const struct policy_node *node); /********************************************* * Report an error on error nodes in a file_context file * node - the node to check * returns NULL if called on a node type other than error node * or a check_result for issue E-002 *********************************************/ struct check_result *check_file_context_error_nodes(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for issues with file context labels user field * node - the node to check * returns NULL if passed or check_result for issue E-003 *********************************************/ struct check_result *check_file_context_users(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for issues with file context labels role field. * Called on NODE_FC_ENTRY nodes. * node - the node to check * returns NULL if passed or check_result for issue E-004 *********************************************/ struct check_result *check_file_context_roles(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for issues with file context labels type field. * Called on NODE_FC_ENTRY nodes. * node - the node to check * returns NULL if passed or check_result for issue E-005 *********************************************/ struct check_result *check_file_context_types_exist(const struct check_data *data, const struct policy_node *node); #endif selint-1.2.1/src/te_checks.h0000644000175100001710000003062614167117255012637 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TE_CHECKS_H #define TE_CHECKS_H #include "check_hooks.h" /********************************************* * Check for violations of te file ordering conventions. * The refpolicy conventions (which is all that can be checked as of now are * described at: https://github.com/SELinuxProject/refpolicy/wiki/StyleGuide * Called on all nodes except fc file nodes, error nodes, NODE_IF_FILE and * NODE_FC_FILE * On NODE_TE_FILE nodes, it generates the ordering information for that file * On other nodes, it checks the previously generated ordering information to * determine whether to return an error. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue C-001 *********************************************/ struct check_result *check_te_order(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for unordered permissions in av rules and class declarations. * Called on NODE_AV_RULE, NODE_XAV_RULE and NODE_DECL nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue C-005 *********************************************/ struct check_result *check_unordered_perms(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for av rules which could use the self keyword but do not. * Note that "av_rule attr_name self:..." and "av_rule attr_name attr_name:..." * Are not identical in behavior, so this should only detect types, not * attributes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue C-007 *********************************************/ struct check_result *check_no_self(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for the presence of require blocks in TE files. * Interface calls are to be preferred. * Called on NODE_REQUIRE and NODE_GEN_REQ nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue S-001 *********************************************/ struct check_result *check_require_block(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for useless semicolons after interface calls * Called on IF_CALL nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue S-003 *********************************************/ struct check_result *check_useless_semicolon(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for bare module statements * Called on NODE_HEADER nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue S-006 *********************************************/ struct check_result *check_bare_module_statement(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for name mismatch between permission macro and class name. * Called on NODE_AV_RULE nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue S-009 *********************************************/ struct check_result *check_perm_macro_class_mismatch(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for used permissions available by a permission macro * Called on NODE_AV_RULE nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue S-010 *********************************************/ struct check_result *check_perm_macro_available(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for references to types in te files without an explicit declaration. * We don't check types in .if or .fc files because those are similar issues * handled by W-002 and E-005 respectively. * This situation typically results in a compilation error, but in the event * that an earlier interface call required the type it would not. * Called on allow rule and interface call nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue W-001 *********************************************/ struct check_result *check_no_explicit_declaration(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for situations where interface or template calls into modules are not * in optional policy blocks * Called on NODE_IF_CALL nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue W-005 *********************************************/ struct check_result *check_module_if_call_in_optional(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for interface calls with empty argument * Called on NODE_IF_CALL nodes * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue W-006 *********************************************/ struct check_result *check_empty_if_call_arg(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for unquoted space in argument of interface calls * Called on NODE_IF_CALL nodes * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue W-007 *********************************************/ struct check_result *check_space_if_call_arg(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for allow rule with complement or wildcard permission * Called on NODE_AV_RULE nodes * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue W-008 *********************************************/ struct check_result *check_risky_allow_perm(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for mismatch of module and file names. * Called on NODE_HEADER nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue W-009 *********************************************/ struct check_result *check_module_file_name_mismatch(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for call of unknown interface. * Called on NODE_IF_CALL nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue W-010 *********************************************/ struct check_result *check_unknown_interface_call(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for clash of declaration and interface names. * This will cause macro expansion to enter an endless loop * and consume all available memory. * Called on NODE_DECL nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue E-006 *********************************************/ struct check_result *check_declaration_interface_nameclash(const struct check_data *data, const struct policy_node *node); /********************************************* * Verify whether the next check can be enabled. *********************************************/ bool check_unknown_permission_condition(void); /********************************************* * Check for usage of unknown permission or permission macro. * Called on NODE_AV_RULE nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue E-007 *********************************************/ struct check_result *check_unknown_permission(const struct check_data *data, const struct policy_node *node); /********************************************* * Verify whether the next check can be enabled. *********************************************/ bool check_unknown_class_condition(void); /********************************************* * Check for usage of unknown class. * Called on NODE_AV_RULE, NODE_RT_RULE and NODE_TT_RULE nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue E-008 *********************************************/ struct check_result *check_unknown_class(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for empty optional and require macro blocks. * Called on NODE_OPTIONAL_POLICY, NODE_GEN_REQ and NODE_REQUIRE nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue E-009 *********************************************/ struct check_result *check_empty_block(const struct check_data *data, const struct policy_node *node); /********************************************* * Check for stray words. * Called on NODE_M4_SIMPLE_MACRO nodes. * data - metadata about the file currently being scanned * node - the node to check * returns NULL if passed or check_result for issue E-010 *********************************************/ struct check_result *check_stray_word(const struct check_data *data, const struct policy_node *node); #endif selint-1.2.1/src/ordering.h0000644000175100001710000002270314167117255012515 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ORDERING_H #define ORDERING_H #include #include "selint_error.h" #include "tree.h" #include "check_hooks.h" enum order_difference_reason { ORDER_EQUAL =0, ORDER_SECTION=1, ORDER_DECLARATION_SUBSECTION, ORDER_LOCAL_SUBSECTION, ORDER_ALPHABETICAL, ORDERING_ERROR=-1024, // Since we will be negating values of this enum // we want it to have a signed internal // representation. The compiler gets to choose which // so by having a negative value explicitly declared // we force it to be signed }; enum local_subsection { LSS_SELF, LSS_OWN, LSS_RELATED, LSS_KERNEL_MOD, LSS_KERNEL, LSS_SYSTEM, LSS_OTHER, LSS_BUILD_OPTION, LSS_BOOLEAN, LSS_TUNABLE, LSS_OPTIONAL, LSS_UNKNOWN, }; struct section_data { char *section_name; // The name of the section this section_data // node contains rules for. This can be either // the name of a type, or a special name beginning // with _. Special names are "_declarations" for // the declarations section at the top and // "_non_ordered" for nodes that should be ignored // in ordering unsigned int lineno_count; unsigned int lines_sum; float avg_line; struct section_data *next; }; struct order_node { const struct policy_node *node; int seq_prev; // The index of previous node in the sequence // or -1 if this is the first node in the sequence int end_of_seq; // This is the index of the smallest value // of an end of a sequence of length i+1, where // i is the index of this node in the array unsigned int in_order; }; struct ordering_metadata { const char *mod_name; struct section_data *sections; size_t order_node_len; struct order_node nodes[]; }; /********************************** * Allocate and initialize an ordering_metadata for the structure. * Calculate the sections and order them. * This function allocates memory for, but does not populate the * nodes[] array. That will be populated on the next pass in the * calculate_longest_increasing_subsequence function. * data (in) - The metadata about the file being scanned * head (in) - Pointer to the file node at the top of the AST * for a file. * * Returns - A new ordering_metadata structure with all memory allocated * and all data except the nodesp[ array populated. The caller is * responsible for freeing all memory. Returns NULL on error **********************************/ struct ordering_metadata *prepare_ordering_metadata(const struct check_data *data, const struct policy_node *head); /********************************** * Calculate the longest increasing subsequence in a given file * Misordered nodes are nodes that are not in this sequence. * Updates the ordering_metadata structure to mark the in order and * out of order nodes in the nodes[] array. * head (in) - Pointer to the file node at the top of the AST * for a file. * ordering (in/out) - A structure of metadata that has been generated * by a call to prepare_ordering_metadata for use in the ordering * comp_func (in) - A function to call for comparison of nodes. It should * return a positive value if the second node should go after the first, * a negative value is the second node should go before the first, and 0 * if the two nodes can go in any relative order. **********************************/ void calculate_longest_increasing_subsequence(const struct policy_node *head, struct ordering_metadata *ordering, enum order_difference_reason (*comp_func)(const struct ordering_metadata *order_data, const struct policy_node *first, const struct policy_node *second)); /********************************** * Add information about a line on lineno in section section_name * to the list of sections **********************************/ enum selint_error add_section_info(struct section_data *sections, const char *section_name, unsigned int lineno); /********************************** * Get the section name for a particular policy node. This is typically * the source type for most node varieties. For the declarations section * at the top it is "_declaration" **********************************/ const char *get_section(const struct policy_node *node); /********************************** * Run through all sections in the section_data linked list and set * the average line number variable for each based on the sum and * count of line numbers **********************************/ void calculate_average_lines(struct section_data *sections); /********************************** * Get the average line number of a section, based on the section name **********************************/ float get_avg_line_by_name(const char *section_name, const struct section_data *sections); /********************************** * Get the subsection within the rules for a domain for a particular policy node **********************************/ enum local_subsection get_local_subsection(const char *mod_name, const struct policy_node *node, enum order_conf variant); /********************************** * Compare two nodes according to the refpolicy ordering conventions * located at https://github.com/SELinuxProject/refpolicy/wiki/StyleGuide * Variant is the config option for how strictly to enforce the style guide. * ORDER_REF - enforce the style guide as written * ORDER_LIGHT - enforce the style guide with the following exceptions: * - No distinction between kernel and system layer, * just kernel module -> non-optional -> optional * ORDER_LAX - enforce the style guide with the following exceptions: * - No ordering restrictions are enforced on the relative ordering * of interface calls and blocks * Return a positive value if the second node should go after the first, * a negative value is the second node should go before the first and * zero if they can go in either order. **********************************/ enum order_difference_reason compare_nodes_refpolicy_generic(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second, enum order_conf variant); /********************************** * Wrapper for compare_nodes_refpolicy_generic for refpolicy ordering **********************************/ enum order_difference_reason compare_nodes_refpolicy(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second); /********************************** * Wrapper for compare_nodes_refpolicy_generic for refpolicy-light ordering **********************************/ enum order_difference_reason compare_nodes_refpolicy_light(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second); /********************************** * Wrapper for compare_nodes_refpolicy_generic for refpolicy-lax ordering **********************************/ enum order_difference_reason compare_nodes_refpolicy_lax(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second); /********************************** * Get a string describing the local subsection. * The strings for kernel and system will be inserted * into a description by get_ordering_reason, so if they * are modified, that code should be modified as well. **********************************/ const char *lss_to_string(enum local_subsection lss); /********************************** * Get a string explaining why a node is out of order. * This is done by looking for the nearest node that is globally * in order and relatively out of order with this node and checking * what the reason for their out of order comparison is **********************************/ char *get_ordering_reason(struct ordering_metadata *order_data, unsigned int index, enum order_conf variant); void free_ordering_metadata(struct ordering_metadata *to_free); void free_section_data(struct section_data *to_free); #endif selint-1.2.1/src/perm_macro.c0000644000175100001710000003646614167117255013036 00000000000000/* * Copyright 2020 The SELint Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include "perm_macro.h" #include "color.h" #include "maps.h" #include "util.h" typedef uint32_t mask_t; struct perm_macro { struct perm_macro *next; char *name; mask_t mask_raw; }; static bool initialized = false; static struct perm_macro *dir_macros = NULL; static struct perm_macro *file_macros = NULL; static struct perm_macro *lnk_file_macros = NULL; static struct perm_macro *chr_file_macros = NULL; static struct perm_macro *blk_file_macros = NULL; static struct perm_macro *sock_file_macros = NULL; static struct perm_macro *fifo_file_macros = NULL; enum pm_common_file { PM_CF__EMPTY = 0u, PM_CF_IOCTL = (1u << 1), PM_CF_READ = (1u << 2), PM_CF_WRITE = (1u << 3), PM_CF_CREATE = (1u << 4), PM_CF_GETATTR = (1u << 5), PM_CF_SETATTR = (1u << 6), PM_CF_LOCK = (1u << 7), PM_CF_RELABELFROM = (1u << 8), PM_CF_RELABELTO = (1u << 9), PM_CF_APPEND = (1u << 10), PM_CF_MAP = (1u << 11), PM_CF_UNLINK = (1u << 12), PM_CF_LINK = (1u << 13), PM_CF_RENAME = (1u << 14), PM_CF_EXECUTE = (1u << 15), PM_CF_MOUNTON = (1u << 16), PM_CF_OPEN = (1u << 17), PM_CF_WATCH = (1u << 18), // dir perms PM_CF_ADDNAME = (1u << 19), PM_CF_REMOVENAME = (1u << 20), PM_CF_REPARENT = (1u << 21), PM_CF_SEARCH = (1u << 23), PM_CF_RMDIR = (1u << 24), // file perms PM_CF_EXECNOTRANS = (1u << 25), PM_CF_ENTRYPOINT = (1u << 26), // perms not covered by macros PM_CF__UNCOVERED = (1u << 31), // extended permissions // these flags contain the original raw permission flag or'ed with // flags of permissions that are reasonable extendable // e.g. open extends getattr and write extends append PM_CF_IOCTL_X = PM_CF_IOCTL, PM_CF_GETATTR_X = PM_CF_GETATTR, PM_CF_READ_X = PM_CF_READ | PM_CF_IOCTL | PM_CF_GETATTR | PM_CF_SEARCH | PM_CF_LOCK, PM_CF_LOCK_X = PM_CF_LOCK | PM_CF_GETATTR, PM_CF_APPEND_X = PM_CF_APPEND | PM_CF_GETATTR, PM_CF_WRITE_X = PM_CF_WRITE | PM_CF_IOCTL | PM_CF_GETATTR | PM_CF_APPEND | PM_CF_LOCK, PM_CF_CREATE_X = PM_CF_CREATE | PM_CF_GETATTR | PM_CF_LINK, PM_CF_SETATTR_X = PM_CF_SETATTR | PM_CF_GETATTR, PM_CF_MAP_X = PM_CF_MAP | PM_CF_IOCTL | PM_CF_GETATTR, PM_CF_UNLINK_X = PM_CF_UNLINK | PM_CF_GETATTR | PM_CF_RMDIR, PM_CF_LINK_X = PM_CF_LINK | PM_CF_GETATTR, PM_CF_RENAME_X = PM_CF_RENAME | PM_CF_GETATTR, PM_CF_OPEN_X = PM_CF_OPEN | PM_CF_GETATTR, PM_CF_EXECUTE_X = PM_CF_EXECUTE | PM_CF_READ | PM_CF_GETATTR | PM_CF_MAP, PM_CF_RELABELFROM_X = PM_CF_RELABELFROM | PM_CF_GETATTR, PM_CF_RELABELTO_X = PM_CF_RELABELTO | PM_CF_GETATTR, PM_CF_MOUNTON_X = PM_CF_MOUNTON | PM_CF_GETATTR, PM_CF_WATCH_X = PM_CF_WATCH | PM_CF_READ, PM_CF_ADDNAME_X = PM_CF_ADDNAME | PM_CF_WRITE_X, PM_CF_REMOVENAME_X = PM_CF_REMOVENAME | PM_CF_WRITE_X, PM_CF_REPARENT_X = PM_CF_REPARENT | PM_CF_GETATTR, PM_CF_SEARCH_X = PM_CF_SEARCH | PM_CF_GETATTR, PM_CF_RMDIR_X = PM_CF_RMDIR | PM_CF_UNLINK_X, PM_CF_EXECNOTRANS_X = PM_CF_EXECNOTRANS | PM_CF_EXECUTE_X, PM_CF_ENTRYPOINT_X = PM_CF_ENTRYPOINT, PM_CF__UNCOVERED_X = PM_CF__UNCOVERED, }; struct pm_ltable { const char *string; enum pm_common_file flag_raw; enum pm_common_file flag_extended; }; static const struct pm_ltable pm_ltable_common_file[] = { { "ioctl", PM_CF_IOCTL, PM_CF_IOCTL_X }, { "read", PM_CF_READ, PM_CF_READ_X }, { "write", PM_CF_WRITE, PM_CF_WRITE_X }, { "create", PM_CF_CREATE, PM_CF_CREATE_X }, { "getattr", PM_CF_GETATTR, PM_CF_GETATTR_X }, { "setattr", PM_CF_SETATTR, PM_CF_SETATTR_X }, { "lock", PM_CF_LOCK, PM_CF_LOCK_X }, { "relabelfrom", PM_CF_RELABELFROM, PM_CF_RELABELFROM_X }, { "relabelto", PM_CF_RELABELTO, PM_CF_RELABELTO_X }, { "append", PM_CF_APPEND, PM_CF_APPEND_X }, { "map", PM_CF_MAP, PM_CF_MAP_X }, { "unlink", PM_CF_UNLINK, PM_CF_UNLINK_X }, { "link", PM_CF_LINK, PM_CF_LINK_X }, { "rename", PM_CF_RENAME, PM_CF_RENAME_X }, { "execute", PM_CF_EXECUTE, PM_CF_EXECUTE_X }, { "mounton", PM_CF_MOUNTON, PM_CF_MOUNTON_X }, { "open", PM_CF_OPEN, PM_CF_OPEN_X }, { "watch", PM_CF_WATCH, PM_CF_WATCH_X }, // dir perms { "add_name", PM_CF_ADDNAME, PM_CF_ADDNAME_X }, { "remove_name", PM_CF_REMOVENAME, PM_CF_REMOVENAME_X }, { "reparent", PM_CF_REPARENT, PM_CF_REPARENT_X }, { "search", PM_CF_SEARCH, PM_CF_SEARCH_X }, { "rmdir", PM_CF_RMDIR, PM_CF_RMDIR_X }, // file perms { "execute_no_trans", PM_CF_EXECNOTRANS, PM_CF_EXECNOTRANS_X }, { "entrypoint", PM_CF_ENTRYPOINT, PM_CF_ENTRYPOINT_X }, // uncovered perms { "quotaon", PM_CF__UNCOVERED, PM_CF__UNCOVERED_X }, { "audit_access", PM_CF__UNCOVERED, PM_CF__UNCOVERED_X }, { "execmod", PM_CF__UNCOVERED, PM_CF__UNCOVERED_X }, { "watch_mount", PM_CF__UNCOVERED, PM_CF__UNCOVERED_X }, { "watch_sb", PM_CF__UNCOVERED, PM_CF__UNCOVERED_X }, { "watch_with_perm", PM_CF__UNCOVERED, PM_CF__UNCOVERED_X }, { "watch_reads", PM_CF__UNCOVERED, PM_CF__UNCOVERED_X }, }; unsigned short popcount(mask_t mask); void compute_perm_mask(const struct string_list *permissions, mask_t *mask_raw, mask_t *mask_extended); static void str_to_mask(const char *permission, mask_t *mask_raw, mask_t *mask_extended) { for (size_t i = 0; i < (sizeof pm_ltable_common_file / sizeof *pm_ltable_common_file); ++i) { if (0 == strcmp(permission, pm_ltable_common_file[i].string)) { *mask_raw |= pm_ltable_common_file[i].flag_raw; *mask_extended |= pm_ltable_common_file[i].flag_extended; return; } } const struct string_list *macro_perms = look_up_in_permmacros_map(permission); if (macro_perms) { compute_perm_mask(macro_perms, mask_raw, mask_extended); return; } // treat unknown permission as uncovered *mask_raw |= PM_CF__UNCOVERED; *mask_extended |= PM_CF__UNCOVERED; } void compute_perm_mask(const struct string_list *permissions, mask_t *mask_raw, mask_t *mask_extended) { for (; permissions; permissions = permissions->next) { str_to_mask(permissions->string, mask_raw, mask_extended); } } struct string_builder { char *mem; size_t len; size_t cap; }; static struct string_builder *sb_create(size_t init_cap) { if (init_cap == 0) { init_cap = 32; } struct string_builder *ret = malloc(sizeof(struct string_builder)); ret->mem = malloc(sizeof(char) * init_cap); ret->mem[0] = '\0'; ret->len = 0; ret->cap = init_cap; return ret; } static void sb_destroy(struct string_builder *sb) { if (sb == NULL) { return; } free(sb->mem); free(sb); } static void sb_append_strn(struct string_builder *sb, const char *str, size_t len) { while (sb->len + len + 1 > sb->cap) { sb->mem = realloc(sb->mem, 2 * sb->cap); sb->cap = 2 * sb->cap; } memcpy(sb->mem + sb->len, str, len); sb->len += len; sb->mem[sb->len] = '\0'; } static void sb_append_str(struct string_builder *sb, const char *str) { sb_append_strn(sb, str, strlen(str)); } static char *sb_decouple_str(struct string_builder *sb) { char *ret = sb->mem; sb->mem = NULL; sb_destroy(sb); return ret; } static char *mask_to_str(mask_t mask) { struct string_builder *sb = sb_create(0); if (mask == PM_CF__EMPTY) { sb_append_str(sb, "(none)"); return sb_decouple_str(sb); } if (mask & PM_CF__UNCOVERED) { printf("%sInternal Error%s: mask_to_str() called with unsupported permission\n", color_error(), color_reset()); sb_append_str(sb, "(unsupported perm)"); return sb_decouple_str(sb); } sb_append_str(sb, "{ "); for (size_t i = 0; i < (sizeof pm_ltable_common_file / sizeof *pm_ltable_common_file); ++i) { if (mask & pm_ltable_common_file[i].flag_raw) { sb_append_str(sb, pm_ltable_common_file[i].string); sb_append_str(sb, " "); mask &= (mask_t)(~pm_ltable_common_file[i].flag_raw); } } sb_append_str(sb, "}"); return sb_decouple_str(sb); } static char *permission_strings_matched_str(const struct string_list *permissions, mask_t mask) { struct string_builder *sb = sb_create(0); sb_append_str(sb, "{ "); for (; permissions; permissions = permissions->next) { mask_t mask_raw = 0, mask_extended = 0; str_to_mask(permissions->string, &mask_raw, &mask_extended); if ((mask_raw & mask) == mask_raw) { sb_append_str(sb, permissions->string); sb_append_str(sb, " "); } } sb_append_str(sb, "}"); return sb_decouple_str(sb); } static unsigned short permission_strings_matched_count(const struct string_list *permissions, mask_t mask) { unsigned short count = 0; for (; permissions; permissions = permissions->next) { mask_t mask_raw = 0, mask_extended = 0; str_to_mask(permissions->string, &mask_raw, &mask_extended); if ((mask_raw & mask) == mask_raw) { count++; } } return count; } unsigned short popcount(mask_t mask) { unsigned short c = 0; for (; mask != 0; mask &= mask - 1) { c++; } return c; } static void load_permission_macro(const char *name, const struct string_list *permissions) { mask_t mask_raw = PM_CF__EMPTY; mask_t mask_extended = PM_CF__EMPTY; compute_perm_mask(permissions, &mask_raw, &mask_extended); // skip macros containing uncovered permissions if (mask_raw & PM_CF__UNCOVERED) { return; } struct perm_macro **category; if (ends_with(name, strlen(name), "_dir_perms", strlen("_dir_perms"))) { category = &dir_macros; } else if (ends_with(name, strlen(name), "_lnk_file_perms", strlen("_lnk_file_perms"))) { category = &lnk_file_macros; } else if (ends_with(name, strlen(name), "_chr_file_perms", strlen("_chr_file_perms"))) { category = &chr_file_macros; } else if (ends_with(name, strlen(name), "_term_perms", strlen("_term_perms"))) { category = &chr_file_macros; } else if (ends_with(name, strlen(name), "_blk_file_perms", strlen("_blk_file_perms"))) { category = &blk_file_macros; } else if (ends_with(name, strlen(name), "_sock_file_perms", strlen("_sock_file_perms"))) { category = &sock_file_macros; } else if (ends_with(name, strlen(name), "_fifo_file_perms", strlen("_fifo_file_perms"))) { category = &fifo_file_macros; } else if (ends_with(name, strlen(name), "_file_perms", strlen("_file_perms"))) { category = &file_macros; } else { // macro for unsupported class return; } struct perm_macro *tmp = malloc(sizeof(struct perm_macro)); tmp->name = strdup(name); tmp->mask_raw = mask_raw; // first entry if (*category == NULL) { tmp->next = NULL; *category = tmp; return; } // sort the permission-macro-list ascending by number of permissions const unsigned short tmp_count_raw = popcount(tmp->mask_raw); struct perm_macro *cur = *category, *prev = NULL; for (;;) { if (tmp_count_raw < popcount(cur->mask_raw)) { if (prev == NULL) { tmp->next = cur; *category = tmp; } else { tmp->next = cur; prev->next = tmp; } return; } if (cur->next == NULL) { tmp->next = NULL; cur->next = tmp; return; } prev = cur; cur = cur->next; } } char *permmacro_check(const char *class, const struct string_list *permissions) { if (!initialized) { visit_all_in_permmacros_map(load_permission_macro); initialized = true; } const struct perm_macro *category; if (0 == strcmp(class, "dir")) { category = dir_macros; } else if (0 == strcmp(class, "file")) { category = file_macros; } else if (0 == strcmp(class, "lnk_file")) { category = lnk_file_macros; } else if (0 == strcmp(class, "chr_file")) { category = chr_file_macros; } else if (0 == strcmp(class, "blk_file")) { category = blk_file_macros; } else if (0 == strcmp(class, "sock_file")) { category = sock_file_macros; } else if (0 == strcmp(class, "fifo_file")) { category = fifo_file_macros; } else { // unsupported class return NULL; } mask_t mask_raw = PM_CF__EMPTY, mask_extended = PM_CF__EMPTY; compute_perm_mask(permissions, &mask_raw, &mask_extended); // ignore av rules containing at most one recognized permission if (popcount(mask_raw & ~PM_CF__UNCOVERED) < 2) { return NULL; } // special extending rules { // extend setattr on create AND write if (mask_extended & (PM_CF_CREATE | PM_CF_WRITE)) { mask_extended |= PM_CF_SETATTR_X; } // extend rename/reparent on create AND unlink/rmdir // (rmdir extends unlink, so PM_CF_UNLINK is set iff PM_CF_RMDIR is set) if (mask_extended & (PM_CF_CREATE | PM_CF_UNLINK)) { mask_extended |= (PM_CF_RENAME_X | PM_CF_REPARENT_X); } } const char *best_name = NULL; unsigned short best_coverage = 0; unsigned short best_extending = 0; mask_t best_mask_raw; for (const struct perm_macro *cur = category; cur; cur= cur->next) { // ignore macros covering additional non-extended permissions if (cur->mask_raw & ~mask_extended) { continue; } const unsigned short coverage = popcount(cur->mask_raw & mask_raw); // ignore macros covering only one used permission if (coverage < 2) { continue; } // ignore macros with less coverage than best yet match if (coverage < best_coverage) { continue; } const unsigned short extending = popcount(cur->mask_raw & ~mask_raw); // ignore macros with equal coverage but more extended permissions if (coverage == best_coverage && extending > best_extending) { continue; } // ignore macros replacing only one permission string, // e.g. { map read_file_perms } should not suggest mmap_read_file_perms replacing { map } // cause read_file_perms include { lock } but mmap_read_file_perms not if (permission_strings_matched_count(permissions, cur->mask_raw & mask_raw) < 2) { continue; } best_name = cur->name; best_coverage = coverage; best_mask_raw = cur->mask_raw; best_extending = extending; } // no macro match found if (!best_name) { return NULL; } // matched macro already used // we match read_file_perms for { read_file_perms }, because its the best match // and we do not discard it prior, cause we do not want to suggest search_dir_perms on list_dir_perms if (str_in_sl(best_name, permissions)) { return NULL; } char *perms_added = mask_to_str(best_mask_raw & ~mask_raw); char *perms_matched = permission_strings_matched_str(permissions, best_mask_raw & mask_raw); #define MSG_STR "Suggesting permission macro: %s (replacing %s, would add %s)" size_t len = (size_t)snprintf(NULL, 0, MSG_STR, best_name, perms_matched, perms_added); char *ret = malloc(len + 1); snprintf(ret, len + 1, MSG_STR, best_name, perms_matched, perms_added); #undef MSG_STR free(perms_matched); free(perms_added); return ret; } static void free_perm_macro(struct perm_macro *to_free) { while (to_free) { struct perm_macro *tmp = to_free->next; free(to_free->name); free(to_free); to_free = tmp; } } void free_permmacros() { initialized = false; free_perm_macro(dir_macros); free_perm_macro(file_macros); free_perm_macro(lnk_file_macros); free_perm_macro(chr_file_macros); free_perm_macro(blk_file_macros); free_perm_macro(sock_file_macros); free_perm_macro(fifo_file_macros); dir_macros = NULL; file_macros = NULL; lnk_file_macros = NULL; chr_file_macros = NULL; blk_file_macros = NULL; sock_file_macros = NULL; fifo_file_macros = NULL; } selint-1.2.1/src/tree.h0000644000175100001710000001542614167117255011647 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TREE_H #define TREE_H #include "selint_error.h" #include "string_list.h" enum node_flavor { NODE_TE_FILE, NODE_IF_FILE, NODE_FC_FILE, NODE_SPT_FILE, NODE_AV_FILE, NODE_AV_RULE, NODE_XAV_RULE, NODE_TT_RULE, NODE_RT_RULE, NODE_HEADER, NODE_ROLE_ALLOW, NODE_ROLE_TYPES, NODE_DECL, NODE_ALIAS, NODE_TYPE_ALIAS, NODE_TYPE_ATTRIBUTE, NODE_ROLE_ATTRIBUTE, NODE_M4_CALL, NODE_M4_SIMPLE_MACRO, NODE_DEFINE, NODE_OPTIONAL_POLICY, NODE_OPTIONAL_ELSE, NODE_BOOLEAN_POLICY, NODE_TUNABLE_POLICY, NODE_IFDEF, NODE_IFELSE, NODE_M4_ARG, NODE_START_BLOCK, NODE_INTERFACE_DEF, NODE_TEMP_DEF, NODE_IF_CALL, NODE_REQUIRE, NODE_GEN_REQ, NODE_PERMISSIVE, NODE_FC_ENTRY, NODE_COMMENT, NODE_EMPTY, NODE_SEMICOLON, // A semicolon that is not needed to close the previous line NODE_CLEANUP, // Called after each file parsing is complete so that checks // that register on this node have a way to clean up state NODE_ERROR // When a parsing error occurs, save an error node in the tree // NODE_ERROR must be the last item in the node_flavor enum // as check_hooks.c assumes it when allocating an array of // length equal to the number of node types }; enum header_flavor { HEADER_BARE, HEADER_MACRO }; enum av_rule_flavor { AV_RULE_ALLOW, AV_RULE_AUDITALLOW, AV_RULE_DONTAUDIT, AV_RULE_NEVERALLOW }; enum decl_flavor { DECL_TYPE, DECL_ATTRIBUTE, DECL_ATTRIBUTE_ROLE, DECL_ROLE, DECL_USER, DECL_CLASS, DECL_PERM, DECL_BOOL }; enum attr_flavor { ATTR_TYPE, ATTR_ROLE }; enum tt_flavor { TT_TT, TT_TM, TT_TC, TT_RT }; struct header_data { enum header_flavor flavor; char *module_name; }; #define AV_RULE_MEMBERS \ enum av_rule_flavor flavor;\ struct string_list *sources;\ struct string_list *targets;\ struct string_list *object_classes;\ struct string_list *perms; struct av_rule_data { AV_RULE_MEMBERS; }; struct xav_rule_data { AV_RULE_MEMBERS; // All xav_rule specific members MUST go after AV_RULE ones char *operation; }; struct role_allow_data { struct string_list *from; struct string_list *to; }; struct role_types_data { char *role; struct string_list *types; }; struct type_transition_data { struct string_list *sources; struct string_list *targets; struct string_list *object_classes; char *default_type; char *name; enum tt_flavor flavor; }; struct role_transition_data { struct string_list *sources; struct string_list *targets; struct string_list *object_classes; char *default_role; }; struct if_call_data { char *name; struct string_list *args; }; struct if_call_list { struct if_call_data *call; struct if_call_list *next; }; struct declaration_data { enum decl_flavor flavor; char *name; struct string_list *attrs; }; struct decl_list { struct declaration_data *decl; struct decl_list *next; }; struct sel_context { int has_gen_context; // 1 if context is wrapped in gen_context, 0 if not char *user; char *role; char *type; char *range; }; struct fc_entry { char *path; char obj; struct sel_context *context; }; struct attribute_data { char *type; struct string_list *attrs; enum attr_flavor flavor; }; struct gen_require_data { unsigned char unquoted; }; union node_data { struct header_data *h_data; struct av_rule_data *av_data; struct xav_rule_data *xav_data; struct role_allow_data *ra_data; struct role_types_data *rtyp_data; struct type_transition_data *tt_data; struct role_transition_data *rt_data; struct if_call_data *ic_data; struct declaration_data *d_data; struct fc_entry *fc_data; struct attribute_data *at_data; struct gen_require_data *gr_data; char *str; }; struct policy_node { struct policy_node *parent; struct policy_node *next; struct policy_node *prev; struct policy_node *first_child; enum node_flavor flavor; union node_data data; char *exceptions; unsigned int lineno; }; enum selint_error insert_policy_node_child(struct policy_node *parent, enum node_flavor flavor, union node_data data, unsigned int lineno); enum selint_error insert_policy_node_next(struct policy_node *prev, enum node_flavor flavor, union node_data data, unsigned int lineno); // Returns 1 if the node is a template call, and 0 if not int is_template_call(const struct policy_node *node); const char *get_name_if_in_template(const struct policy_node *cur); struct string_list *get_names_in_node(const struct policy_node *node); struct string_list *get_names_required(const struct policy_node *node); const char *decl_flavor_to_string(enum decl_flavor flavor); /********************************** * Return 1 if the node is in a require block * and 0 otherwise **********************************/ int is_in_require(const struct policy_node *cur); //Return the next node in a depth first search of the tree struct policy_node *dfs_next(const struct policy_node *node); enum selint_error free_policy_node(struct policy_node *to_free); enum selint_error free_header_data(struct header_data *to_free); enum selint_error free_av_rule_data(struct av_rule_data *to_free); enum selint_error free_xav_rule_data(struct xav_rule_data *to_free); enum selint_error free_ra_data(struct role_allow_data *to_free); enum selint_error free_rtyp_data(struct role_types_data *to_free); enum selint_error free_type_transition_data(struct type_transition_data *to_free); enum selint_error free_role_transition_data(struct role_transition_data *to_free); enum selint_error free_if_call_data(struct if_call_data *to_free); enum selint_error free_declaration_data(struct declaration_data *to_free); enum selint_error free_decl_list(struct decl_list *to_free); // Only free the list, not what it's pointing to enum selint_error free_if_call_list(struct if_call_list *to_free); void free_fc_entry(struct fc_entry *to_free); void free_sel_context(struct sel_context *to_free); void free_attribute_data(struct attribute_data *to_free); void free_gen_require_data(struct gen_require_data *to_free); #endif selint-1.2.1/src/lex.l0000644000175100001710000001610314167117255011475 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ %{ #include #include #include "tree.h" #include "parse.h" extern void reset_current_lines(void); /* * Callback by the lexer, called prior to every matched rule's action. * Update the source file location accordingly. */ #define YY_USER_ACTION \ yylloc->first_line = yylloc->last_line = yylineno; \ yylloc->first_column = yycolumn; \ yylloc->last_column = yycolumn + yyleng - 1; \ yycolumn += yyleng; // used by parser char* current_lines[LINES_TO_CACHE] = { NULL }; unsigned line_cache_index = 0; // internal state for cached lines static size_t current_lines_alloc[LINES_TO_CACHE] = { 0 }; static size_t current_line_sent = 0; static size_t current_line_len = 0; void reset_current_lines(void) { for (unsigned i = 0; i < LINES_TO_CACHE; ++i) { free(current_lines[i]); current_lines[i] = NULL; current_lines_alloc[i] = 0; } line_cache_index = 0; current_line_sent = current_line_len = 0; } /* * Override the input method of the lexer. * Read a complete line and save it for error printing. * Must be a macro to access yyin. */ #undef YY_INPUT #define YY_INPUT(buf, result, max_size) \ size_t _avail = current_line_len - current_line_sent; \ if (_avail == 0) { \ current_line_sent = 0; \ line_cache_index = (line_cache_index + 1) % LINES_TO_CACHE; \ const ssize_t _res = getline(¤t_lines[line_cache_index], \ ¤t_lines_alloc[line_cache_index], \ yyin); \ if (_res < 0) { \ if (ferror(yyin)) { \ YY_FATAL_ERROR("Error reading input"); \ } \ _avail = 0; \ current_lines[line_cache_index][0] = '\0'; \ } else { \ _avail = (size_t)_res; \ } \ current_line_len = _avail; \ } \ if (_avail > (size_t)(max_size)) { \ _avail = (size_t)(max_size); \ } \ memcpy((buf), current_lines[line_cache_index] + current_line_sent, _avail); \ current_line_sent += _avail; \ (result) = (int)_avail; %} %option nounput %option noinput %option noyywrap %option nodefault %option yylineno %option reentrant %option bison-bridge %option bison-locations %% policy_module { return POLICY_MODULE; } module { return MODULE; } type { return TYPE; } typealias { return TYPEALIAS; } alias { return ALIAS; } attribute { return ATTRIBUTE; } bool { return BOOL; } typeattribute { return TYPE_ATTRIBUTE; } roleattribute { return ROLE_ATTRIBUTE; } role { return ROLE; } types { return TYPES; } attribute_role { return ATTRIBUTE_ROLE; } allow { return ALLOW; } allowxperm { return ALLOW_XPERM; } auditallow { return AUDIT_ALLOW; } auditallowxperm { return AUDIT_ALLOW_XPERM; } dontaudit { return DONT_AUDIT; } dontauditxperm { return DONT_AUDIT_XPERM; } neverallow { return NEVER_ALLOW; } neverallowxperm { return NEVER_ALLOW_XPERM; } type_transition { return TYPE_TRANSITION; } type_member { return TYPE_MEMBER; } type_change { return TYPE_CHANGE; } range_transition { return RANGE_TRANSITION; } role_transition { return ROLE_TRANSITION; } optional_policy { return OPTIONAL_POLICY; } gen_require { return GEN_REQUIRE; } gen_bool { return GEN_BOOL; } gen_tunable { return GEN_TUNABLE; } require { return REQUIRE; } tunable_policy { return TUNABLE_POLICY; } ifelse { return IFELSE; } refpolicywarn { return REFPOLICYWARN; } class { return CLASS; } common { return COMMON; } inherits { return INHERITS; } if { return IF; } else { return ELSE; } ifdef { return IFDEF; } ifndef { return IFNDEF; } genfscon { return GENFSCON; } sid { return SID; } portcon { return PORTCON; } netifcon { return NETIFCON; } nodecon { return NODECON; } fs_use_trans { return FS_USE_TRANS; } fs_use_xattr { return FS_USE_XATTR; } fs_use_task { return FS_USE_TASK; } define { return DEFINE; } gen_user { return GEN_USER; } gen_context { return GEN_CONTEXT; } permissive { return PERMISSIVE; } typebounds { return TYPEBOUNDS; } interface { return INTERFACE; } template { return TEMPLATE; } userdebug_or_eng { return USERDEBUG_OR_ENG; } [0-9]+\.[0-9]+(\.[0-9]+)? { yylval->string = strdup(yytext); return VERSION_NO; } [0-9]+ { yylval->string = strdup(yytext); return NUMBER; } [a-zA-Z\$\/][a-zA-Z0-9_\$\*\/\-]* { yylval->string = strdup(yytext); return STRING; } [0-9a-zA-Z\$\/][a-zA-Z0-9_\$\*\/\-]* { yylval->string = strdup(yytext); return NUM_STRING; } [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} { yylval->string = strdup(yytext); return IPV4; } ([0-9A-Fa-f]{1,4})?\:([0-9A-Fa-f\:])*\:([0-9A-Fa-f]{1,4})?(\:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})? { yylval->string = strdup(yytext); return IPV6; } \"[a-zA-Z0-9_\.\-\:~\$]*\" { yylval->string = strdup(yytext); return QUOTED_STRING; } \-[\-ldbcsp][ \t] { return FILE_TYPE_SPECIFIER; } \( { return OPEN_PAREN; } \) { return CLOSE_PAREN; } \, { return COMMA; } \. { return PERIOD; } \{ { return OPEN_CURLY; } \} { return CLOSE_CURLY; } \: { return COLON; } \; { return SEMICOLON; } \` { return BACKTICK; } \' { return SINGLE_QUOTE; } \~ { return TILDA; } \* { return STAR; } \- { return DASH; } \&\& { return AND; } \|\| { return OR; } \^ { return XOR; } \!\= { return NOT_EQUAL; } \! { return NOT; } \=\= { return EQUAL; } \#selint\-disable\:\ ?[CSWEF]\-[0-9]+(\,\ ?[CSWEF]\-[0-9]+)*$ { yylval->string = strdup(yytext); return SELINT_COMMAND; } \#.*$ { return COMMENT; } dnl(.*)?$ ; /* skip m4 comment lines */ [ \t\n\r] ; /* normally skip whitespace */ . { yylval->symbol = *yytext; return UNKNOWN_TOKEN; } selint-1.2.1/src/template.h0000644000175100001710000000265014167117255012516 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TEMPLATE_H #define TEMPLATE_H // Functions for dealing with declarations in templates #include "selint_error.h" #include "tree.h" /* Replace bash style arguments with a string */ char *replace_m4(const char *orig, const struct string_list *args); /* Loop over replace_from string_list and call replace_m4 on each string in it, using the * strings in replace_with as the arguments. */ struct string_list *replace_m4_list(const struct string_list *replace_with, const struct string_list *replace_from); enum selint_error add_template_declarations(const char *template_name, const struct string_list *args, struct string_list *parent_temp_names, const char *mod_name); #endif selint-1.2.1/src/string_list.h0000644000175100001710000000365314167117255013250 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef STRING_LIST_H #define STRING_LIST_H #include #include "selint_error.h" struct string_list { char *string; struct string_list *next; int has_incorrect_space; }; int str_in_sl(const char *str, const struct string_list *sl); // Return an identical copy of sl struct string_list *copy_string_list(const struct string_list *sl); // Return a string list with a copy of the given string as single item struct string_list *sl_from_str(const char *string); struct string_list *sl_from_strn(const char *string, size_t len); // Return a string list with the given string as single item // Takes ownership of the given string struct string_list *sl_from_str_consume(char *string); // Return a string list with copies of the given strings struct string_list *sl_from_strs(int count, ...); // Concat two string lists, accepts NULL lists. // Note: freeing the returned list will free both original string lists struct string_list *concat_string_lists(struct string_list *head, struct string_list *tail); // Append a copy of a string on the end of the given string list // Note: this traverses the string list. In performance critical // situations with multiple appends, you should save a pointer to the end of the list enum selint_error append_to_sl(struct string_list *sl, const char *string); void free_string_list(struct string_list *list); #endif selint-1.2.1/src/color.c0000644000175100001710000000326214167117255012014 00000000000000/* * Copyright 2020 The SELint Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "color.h" static int enabled = 0; #define COLOR_RESET "\033[0m" #define COLOR_BOLD "\033[1m" #define COLOR_RED "\033[31;1m" #define COLOR_GREEN "\033[32;1m" #define COLOR_YELLOW "\033[33;1m" #define COLOR_BLUE "\033[34;1m" #define COLOR_MAGENTA "\033[35;1m" #define COLOR_CYAN "\033[36;1m" #define EMPTY_STR "" void color_enable() { enabled = 1; } const char *color_reset() { if (!enabled) { return EMPTY_STR; } return COLOR_RESET; } const char *color_error() { if (!enabled) { return EMPTY_STR; } return COLOR_RED; } const char *color_warning() { if (!enabled) { return EMPTY_STR; } return COLOR_YELLOW; } const char *color_note() { if (!enabled) { return EMPTY_STR; } return COLOR_MAGENTA; } const char *color_ok() { if (!enabled) { return EMPTY_STR; } return COLOR_GREEN; } const char *color_severity(char severity) { if (!enabled) { return EMPTY_STR; } switch (severity) { case 'E': return COLOR_RED; case 'W': return COLOR_YELLOW; case 'S': return COLOR_MAGENTA; case 'C': return COLOR_BLUE; } return COLOR_BOLD; } selint-1.2.1/src/color.h0000644000175100001710000000410614167117255012017 00000000000000/* * Copyright 2020 The SELint Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef COLOR_H #define COLOR_H /********************************************* * Enable colored output. * All color functions only return color control sequences, if colored output has been enabled. * Prior to that all color functions return an empty string. *********************************************/ void color_enable(void); /********************************************* * Reset any previous color setting. * Should be used after any marking color function. *********************************************/ const char *color_reset(void); /********************************************* * Mark the following output with an error color. *********************************************/ const char *color_error(void); /********************************************* * Mark the following output with a warning color. *********************************************/ const char *color_warning(void); /********************************************* * Mark the following output with a note color. *********************************************/ const char *color_note(void); /********************************************* * Mark the following output with an ok color. *********************************************/ const char *color_ok(void); /********************************************* * Mark the following output with the appropriate color for the given severity. * severity - The severity to decide the color. *********************************************/ const char *color_severity(char severity); #endif /* COLOR_H */ selint-1.2.1/src/runner.h0000644000175100001710000001400514167117255012211 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNNER_H #define RUNNER_H #include "check_hooks.h" #include "selint_error.h" #include "parse_functions.h" #include "file_list.h" /**************************************************** * Parse a policy file * filename - The name of the files to parse. * flavor - The node type corresponding to the type of file (TE or IF) * Returns the head of the parsed AST or NULL on failure ****************************************************/ struct policy_node *parse_one_file(const char *filename, enum node_flavor flavor); /**************************************************** * Determine whether a specific check is enabled based on the * config file and the command line arguments ****************************************************/ int is_check_enabled(const char *check_name, const struct string_list *config_enabled_checks, const struct string_list *config_disabled_checks, const struct string_list *cl_enabled_checks, const struct string_list *cl_disabled_checks, int only_enabled); /**************************************************** * Allocate and populate a checks structure with the list of checks enabled for * this run. Caller is responsible for freeing * level - The severity level to load checks at and above * Returns the allocated checks structure or NULL on failure ****************************************************/ struct checks *register_checks(char level, const struct string_list *config_enabled_checks, const struct string_list *config_disabled_checks, const struct string_list *cl_enabled_checks, const struct string_list *cl_disabled_checks, int only_enabled); /**************************************************** * Parse all the provided te or if files, storing their parsed ASTs * in the provided list * files - The files to parse. This list is updated with parsed ASTs * flavor - The node type corresponding to the sorts of files in this list * Returns SELINT_SUCCESS on success or an error code ****************************************************/ enum selint_error parse_all_files_in_list(struct policy_file_list *files, enum node_flavor flavor); /**************************************************** * Parse all the provided fc files, storing their parsed ASTs * in the provided list * files - The files to parse. This list is updated with parsed ASTs * Returns SELINT_SUCCESS on success or an error code ****************************************************/ enum selint_error parse_all_fc_files_in_list(struct policy_file_list *files, const struct string_list *custom_fc_macros); /**************************************************** * Run all checks for a certain file * ck - The checks structure * data - metadata about the file * head - The head of the AST for that file * Returns SELINT_SUCCESS on success or an error code ****************************************************/ enum selint_error run_checks_on_one_file(struct checks *ck, const struct check_data *data, const struct policy_node *head); /**************************************************** * Run all checks on all files of a certain type (te, if or fc) * ck - The checks structure * flavor - The type of file to check * files - The list of files of that type to check * Returns SELINT_SUCCESS on success or an error code ****************************************************/ enum selint_error run_all_checks(struct checks *ck, enum file_flavor flavor, struct policy_file_list *files, const struct config_check_data *ccd); /**************************************************** * Run the complete analysis, checking all files and reporting results * ck - The checks structure * te_files - The list of te files to check * if_files - The list of if files to check * fc_files - The list of fc files to check * context_te_files - Additional te files to parse, but not scan. This is used * to load symbols (eg type names) that may be referenced in scanned files. * context_if_files - Additional if files to parse, but not scan. This is used * to load interface/template names and contents to do analysis on how they are * used in scanned files. * custom_fc_macros - Custom macros used in fc files defined in config * ccd - Information loaded from the config to be given to checks * Returns SELINT_SUCCESS on success or an error code ****************************************************/ enum selint_error run_analysis(struct checks *ck, struct policy_file_list *te_files, struct policy_file_list *if_files, struct policy_file_list *fc_files, struct policy_file_list *context_te_files, struct policy_file_list *context_if_files, const struct string_list *custom_fc_macros, const struct config_check_data *ccd); /**************************************************** * Display a summary of the analysis that was just run * ck - The checks structure * no return ****************************************************/ void display_run_summary(const struct checks *ck); #endif selint-1.2.1/src/selint_config.h0000644000175100001710000000340314167117255013523 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CONFIG_H #define CONFIG_H #include #include "selint_error.h" #include "string_list.h" #include "tree.h" #include "maps.h" enum order_conf { ORDER_REF, ORDER_LIGHT, ORDER_LAX }; struct config_check_data { enum order_conf order_conf; enum decl_flavor order_requires[6]; bool ordering_requires_same_flavor; bool skip_checking_generated_fcs; struct string_list *custom_te_simple_macros; }; /******************************************************************* * Parse the config file and set the function arguments appropriately * Return SELINT_SUCCESS or error code ********************************************************************/ enum selint_error parse_config(const char *config_filename, int in_source_mode, char *severity, struct string_list **config_disabled_checks, struct string_list **config_enabled_checks, struct string_list **custom_fc_macros, struct config_check_data *config_check_data); void free_selint_config(struct config_check_data *config_check_data); #endif selint-1.2.1/src/main.c0000644000175100001710000004744314167117255011633 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include "runner.h" #include "parse.h" #include "config.h" #include "file_list.h" #include "util.h" #include "selint_config.h" #include "startup.h" #include "color.h" // ASCII characters go up to 127 #define CONTEXT_ID 128 #define COLOR_ID 129 #define SUMMARY_ONLY_ID 130 #define SCAN_HIDDEN_DIRS_ID 131 #define DEBUG_PARSER_ID 132 extern int yydebug; extern int verbose_flag; static void usage(void) { /* *INDENT-OFF* */ printf("Usage: selint [OPTIONS] FILE [...]\n"\ "Perform static code analysis on SELinux policy source.\n\n"); printf(" -c, --config=CONFIGFILE\tOverride default config with config\n"\ "\t\t\t\tspecified on command line. See\n"\ "\t\t\t\tCONFIGURATION section for config file syntax.\n"\ " --color=COLOR_OPTION\tConfigure color output.\n"\ "\t\t\t\tOptions are on, off and auto (the default).\n"\ " --context=CONTEXT_PATH\tRecursively scan CONTEXT_PATH to find additional te and if\n"\ "\t\t\t\tfiles to parse, but not scan. SELint will assume the scanned policy files\n"\ "\t\t\t\tare intended to be compiled together with the context files.\n"\ "\t\t\t\tare intended to be compiled together with the context files. Implies -s.\n"\ " --debug-parser\t\tEnable debug output for the internal policy parser.\n"\ "\t\t\t\tVery noisy, useful to debug parsing failures.\n"\ " -d, --disable=CHECKID\t\tDisable check with the given ID.\n"\ " -e, --enable=CHECKID\t\tEnable check with the given ID.\n"\ " -E, --only-enabled\t\tOnly run checks that are explicitly enabled with\n"\ "\t\t\t\tthe --enable option.\n"\ " -F, --fail\t\t\tExit with a non-zero value if any issue was found.\n"\ " -h, --help\t\t\tDisplay this menu.\n"\ " -l, --level=LEVEL\t\tOnly list errors with a severity level at or\n"\ "\t\t\t\tgreater than LEVEL. Options are C (convention), S (style),\n"\ "\t\t\t\tW (warning), E (error), F (fatal error).\n"\ " --scan-hidden-dirs\tScan hidden directories.\n"\ "\t\t\t\tBy default hidden directories (like '.git') are skipped in recursive mode.\n"\ " -s, --source\t\t\tRun in \"source mode\" to scan a policy source repository\n"\ "\t\t\t\tthat is designed to compile into a full system policy.\n"\ " -S, --summary\t\t\tDisplay a summary of issues found after running the analysis.\n"\ " --summary-only\t\tOnly display a summary of issues found after running the analysis.\n"\ "\t\t\t\tDo not show the individual findings. Implies -S.\n"\ " -r, --recursive\t\tScan recursively and check all SELinux policy files found.\n"\ " -v, --verbose\t\t\tEnable verbose output.\n"\ " -V, --version\t\t\tShow version information and exit.\n" ); /* *INDENT-ON* */ } #define WARN_ON_INVALID_CHECK_ID(id, desc)\ if (!is_valid_check(id)) {\ printf("%sWarning%s: %s, %s, is not a valid check id.\n", color_warning(), color_reset(), id, desc);\ } int main(int argc, char **argv) { char severity = '\0'; const char *config_filename = NULL; int source_flag = 0; int recursive_scan = 0; int only_enabled = 0; int exit_code = EX_OK; int summary_flag = 0; int fail_on_finding = 0; int scan_hidden_dirs = 0; struct string_list *context_paths = NULL; char color = 0; // 0 auto, 1 off, 2 on struct string_list *config_disabled_checks = NULL; struct string_list *config_enabled_checks = NULL; struct string_list *cl_disabled_checks = NULL; struct string_list *cl_enabled_checks = NULL; struct string_list *custom_fc_macros = NULL; struct string_list *cl_e_cursor = NULL; struct string_list *cl_d_cursor = NULL; yydebug = 0; while (1) { static const struct option long_options[] = { { "config", required_argument, NULL, 'c' }, { "context", required_argument, NULL, CONTEXT_ID }, { "debug-parser", no_argument, NULL, DEBUG_PARSER_ID }, { "disable", required_argument, NULL, 'd' }, { "enable", required_argument, NULL, 'e' }, { "fail", no_argument, NULL, 'F' }, { "only-enabled", no_argument, NULL, 'E' }, { "help", no_argument, NULL, 'h' }, { "level", required_argument, NULL, 'l' }, { "modules-conf", required_argument, NULL, 'm' }, { "recursive", no_argument, NULL, 'r' }, { "source", no_argument, NULL, 's' }, { "summary", no_argument, NULL, 'S' }, { "color", required_argument, NULL, COLOR_ID }, { "scan-hidden-dirs", no_argument, NULL, SCAN_HIDDEN_DIRS_ID }, { "summary-only", no_argument, NULL, SUMMARY_ONLY_ID }, { "version", no_argument, NULL, 'V' }, { "verbose", no_argument, &verbose_flag, 1 }, { 0, 0, 0, 0 } }; int option_index = 0; int c = getopt_long(argc, argv, "c:d:e:EFhl:mrsSVv", long_options, &option_index); if (c == -1) { break; } switch (c) { case 0: break; case 'c': // Specify config file config_filename = optarg; break; case CONTEXT_ID: // Specify a path for context files if (!context_paths) { context_paths = sl_from_str(optarg); } else { append_to_sl(context_paths, optarg); } // Don't parse system devel policies if a context is given source_flag = 1; break; case COLOR_ID: if (0 == strcmp(optarg, "on")) { color = 2; } else if (0 == strcmp(optarg, "off")) { color = 1; } else if (0 == strcmp(optarg, "auto")) { color = 0; } else { printf("Invalid argument '%s' given for option --color\n", optarg); usage(); exit(EX_USAGE); } break; case DEBUG_PARSER_ID: // Enable debug mode for the internal parser yydebug = 1; break; case 'd': // Disable a given check if (cl_d_cursor) { cl_d_cursor->next = calloc(1, sizeof(struct string_list)); cl_d_cursor = cl_d_cursor->next; } else { cl_d_cursor = calloc(1, sizeof(struct string_list)); cl_disabled_checks = cl_d_cursor; } cl_d_cursor->string = strdup(optarg); break; case 'e': // Enable a given check if (cl_e_cursor) { cl_e_cursor->next = calloc(1, sizeof(struct string_list)); cl_e_cursor = cl_e_cursor->next; } else { cl_e_cursor = calloc(1, sizeof(struct string_list)); cl_enabled_checks = cl_e_cursor; } cl_e_cursor->string = strdup(optarg); break; case 'E': // Only run checks enabled by the --enable flag. only_enabled = 1; break; case 'F': // Exit non-zero if any issue was found fail_on_finding = 1; break; case 'h': // Display usage info and exit usage(); exit(0); case 'l': // Set the severity level severity = optarg[0]; if (!is_valid_severity(severity)) { printf("Invalid argument '%s' given for option --level\n", optarg); usage(); exit(EX_USAGE); } break; case 'm': // Specify a modules.conf file. (Not in the README) // TODO break; case 'r': // Scan recursively for files to parse recursive_scan = 1; break; case 's': // Run in source mode source_flag = 1; break; case SCAN_HIDDEN_DIRS_ID: // Scan hidden directories in recursive mode scan_hidden_dirs = 1; break; case SUMMARY_ONLY_ID: // Do not display individual findings suppress_output = 1; // FALLTHRU case 'S': // Display a summary at the end of the run summary_flag = 1; break; case 'V': // Output version info and exit printf("SELint %s\n", VERSION); exit(0); case 'v': // Run in verbose mode verbose_flag = 1; break; case '?': usage(); exit(EX_USAGE); } } print_if_verbose("Verbose mode enabled\n"); if (color == 2 || (color == 0 && isatty(STDOUT_FILENO))) { color_enable(); print_if_verbose("Color output enabled\n"); } if (source_flag) { print_if_verbose("Source mode enabled\n"); if (!recursive_scan) { printf("%sNote%s: Source mode enabled without recursive flag (only explicit specified files will be checked).\n", color_note(), color_reset()); } } for (const struct string_list * cur = cl_disabled_checks; cur; cur = cur->next) { WARN_ON_INVALID_CHECK_ID(cur->string, "disabled on command line"); } for (const struct string_list * cur = cl_enabled_checks; cur; cur = cur->next) { WARN_ON_INVALID_CHECK_ID(cur->string, "enabled on command line"); } if (config_filename && 0 != access(config_filename, R_OK)) { printf("%sError%s: No configuration file found at '%s'!\n", color_error(), color_reset(), config_filename); exit(EX_USAGE); } else if (!config_filename) { config_filename = SYSCONFDIR "/selint.conf"; // Default install path if (0 != access(config_filename, R_OK)) { //No default config found print_if_verbose( "No config specified and could not find default config at %s.\n", config_filename); config_filename = NULL; } } struct config_check_data ccd = { ORDER_LAX, {}, true, true, NULL }; if (config_filename) { char cfg_severity; if (SELINT_SUCCESS != parse_config(config_filename, source_flag, &cfg_severity, &config_disabled_checks, &config_enabled_checks, &custom_fc_macros, &ccd)) { // Error message printed by parse_config() exit(EX_CONFIG); } if (severity == '\0') { severity = cfg_severity; } } else { // If there is no config, we should assume the existence of normal users and // roles that we wouldn't otherwise know about insert_into_decl_map("system_u", "__assumed__", DECL_USER); insert_into_decl_map("object_r", "__assumed__", DECL_ROLE); } for (const struct string_list *config_check_id = config_disabled_checks; config_check_id; config_check_id = config_check_id->next) { WARN_ON_INVALID_CHECK_ID(config_check_id->string, "disabled in config"); } for (const struct string_list *config_check_id = config_enabled_checks; config_check_id; config_check_id = config_check_id->next) { WARN_ON_INVALID_CHECK_ID(config_check_id->string, "enabled in config"); } if (only_enabled && !cl_enabled_checks) { printf("%sError%s: no warning enabled!\n", color_error(), color_reset()); exit(EX_USAGE); } if (severity == '\0') { severity = 'C'; } print_if_verbose("Severity level set to %c\n", severity); if (optind == argc) { usage(); exit(EX_USAGE); } struct policy_file_list *te_files = calloc(1, sizeof(struct policy_file_list)); struct policy_file_list *if_files = calloc(1, sizeof(struct policy_file_list)); struct policy_file_list *fc_files = calloc(1, sizeof(struct policy_file_list)); struct policy_file_list *context_te_files = calloc(1, sizeof(struct policy_file_list)); struct policy_file_list *context_if_files = calloc(1, sizeof(struct policy_file_list)); char **paths = malloc(sizeof(char *) * (unsigned)argc - (unsigned)optind + 2); int i = 0; while (optind < argc) { print_if_verbose("Path added to scan: '%s'\n", argv[optind]); paths[i++] = argv[optind++]; } paths[i] = NULL; FTS *ftsp = fts_open(paths, FTS_PHYSICAL | FTS_NOSTAT, NULL); FTSENT *file = fts_read(ftsp); char *modules_conf_path = NULL; char *obj_perm_sets_path = NULL; char *access_vector_path = NULL; while (file) { const char *suffix = (file->fts_pathlen > 3) ? (file->fts_path + file->fts_pathlen - 3) : NULL; if (suffix && !strcmp(suffix, ".te")) { file_list_push_back(te_files, make_policy_file(file->fts_path, NULL)); } else if (suffix && !strcmp(suffix, ".if")) { file_list_push_back(if_files, make_policy_file(file->fts_path, NULL)); char *mod_name = strdup(file->fts_name); mod_name[file->fts_namelen - 3] = '\0'; insert_into_mod_layers_map(mod_name, file->fts_parent->fts_name); free(mod_name); } else if (suffix && !strcmp(suffix, ".fc")) { file_list_push_back(fc_files, make_policy_file(file->fts_path, NULL)); } else if (source_flag && !strcmp(file->fts_name, "modules.conf")) { // TODO: Make modules.conf name configurable modules_conf_path = strdup(file->fts_path); } else if (source_flag && !strcmp(file->fts_name, "obj_perm_sets.spt")) { // TODO: Make obj_perm_sets.spt name configurable obj_perm_sets_path = strdup(file->fts_path); } else if (source_flag && !strcmp(file->fts_name, "access_vectors")) { // TODO: Make access_vectors name configurable access_vector_path = strdup(file->fts_path); } else { // Directories might get traversed twice: preorder and final visit. // Print only the final visit if (file->fts_info != FTS_D) { if (recursive_scan) { print_if_verbose("Skipping %s which is not a policy file\n", file->fts_path); } else { printf("%sNote%s: Skipping %s which is not a policy file\n", color_note(), color_reset(), file->fts_path); } } if (!recursive_scan) { fts_set(ftsp, file, FTS_SKIP); } if (!scan_hidden_dirs && file->fts_info == FTS_D && file->fts_name[0] == '.' && file->fts_name[1] != '.' && file->fts_name[1] != '\0') { print_if_verbose("Skipping hidden directory %s\n", file->fts_path); fts_set(ftsp, file, FTS_SKIP); } } file = fts_read(ftsp); } fts_close(ftsp); struct string_list *context_path_node = context_paths; while (context_path_node) { paths[0] = context_path_node->string; paths[1] = NULL; ftsp = fts_open(paths, FTS_PHYSICAL | FTS_NOSTAT, NULL); file = fts_read(ftsp); while (file) { const char *suffix = (file->fts_pathlen > 3) ? (file->fts_path + file->fts_pathlen - 3) : NULL; if (suffix && !strcmp(suffix, ".te")) { if (!file_name_in_file_list(file->fts_path, te_files)) { file_list_push_back(context_te_files, make_policy_file(file->fts_path, NULL)); } } else if (suffix && !strcmp(suffix, ".if")) { if (!file_name_in_file_list(file->fts_path, if_files)) { file_list_push_back(context_if_files, make_policy_file(file->fts_path, NULL)); } } else if (source_flag && !modules_conf_path && 0 == strcmp(file->fts_name, "modules.conf")) { modules_conf_path = strdup(file->fts_path); } else if (source_flag && !obj_perm_sets_path && 0 == strcmp(file->fts_name, "obj_perm_sets.spt")) { obj_perm_sets_path = strdup(file->fts_path); } else if (source_flag && !access_vector_path && 0 == strcmp(file->fts_name, "access_vectors")) { access_vector_path = strdup(file->fts_path); } file = fts_read(ftsp); } fts_close(ftsp); context_path_node = context_path_node->next; } free_string_list(context_paths); free(paths); // Load object classes and permissions if (source_flag) { if (access_vector_path) { enum selint_error res = load_access_vectors_source(access_vector_path); if (res != SELINT_SUCCESS) { printf("%sWarning%s: Failed to parse access_vectors from %s: %d\n", color_warning(), color_reset(), access_vector_path, res); } else { print_if_verbose("Loaded classes and permissions from %s\n", access_vector_path); } } else { printf("%sWarning%s: Failed to locate access_vectors file.\n", color_warning(), color_reset()); } if (modules_conf_path) { enum selint_error res = load_modules_source(modules_conf_path); if (res != SELINT_SUCCESS) { printf("%sWarning%s: Failed to load modules from %s: %d\n", color_warning(), color_reset(), modules_conf_path, res); } else { print_if_verbose("Loaded modules from %s\n", modules_conf_path); } } else { printf("%sWarning%s: Failed to locate modules.conf file.\n", color_warning(), color_reset()); } if (obj_perm_sets_path) { enum selint_error res = load_obj_perm_sets_source(obj_perm_sets_path); if (res != SELINT_SUCCESS) { printf("%sWarning%s: Failed to permission and class set macros from %s: %d\n", color_warning(), color_reset(), obj_perm_sets_path, res); } else { print_if_verbose("Loaded permission and class set macros from %s\n", obj_perm_sets_path); } } else { printf("%sWarning%s: Failed to locate obj_perm_sets.spt file.\n", color_warning(), color_reset()); } } else { enum selint_error r = load_access_vectors_kernel("/sys/fs/selinux/class"); if (r != SELINT_SUCCESS) { if (r == SELINT_IO_ERROR) { printf("%sNote%s: Failed to load classes and perms probably due to running on a SELinux disabled system.\n", color_note(), color_reset()); } else { printf("%sWarning%s: Failed to load classes and perms from current kernel.\n", color_warning(), color_reset()); } } load_modules_normal(); enum selint_error res = load_devel_headers(context_if_files); if (res != SELINT_SUCCESS) { printf("%sWarning%s: Failed to load SELinux development header files.\n", color_warning(), color_reset()); } } /* Delay until support files have been parsed for check conditions. */ struct checks *ck = register_checks(severity, config_enabled_checks, config_disabled_checks, cl_enabled_checks, cl_disabled_checks, only_enabled); if (!ck) { printf("%sError%s: Failed to register checks (bad configuration)\n", color_error(), color_reset()); free_file_list(te_files); free_file_list(if_files); free_file_list(fc_files); free_file_list(context_te_files); free_file_list(context_if_files); free(obj_perm_sets_path); free(access_vector_path); free(modules_conf_path); return EX_CONFIG; } free(obj_perm_sets_path); free(access_vector_path); free(modules_conf_path); enum selint_error res = run_analysis(ck, te_files, if_files, fc_files, context_te_files, context_if_files, custom_fc_macros, &ccd); switch (res) { case SELINT_SUCCESS: if (summary_flag) { display_run_summary(ck); } break; case SELINT_PARSE_ERROR: printf("%sError%s: Failed to parse files\n", color_error(), color_reset()); exit_code = EX_SOFTWARE; break; default: printf("%sError%s: Internal error: %d\n", color_error(), color_reset(), res); exit_code = EX_SOFTWARE; } if (config_enabled_checks) { free_string_list(config_enabled_checks); } if (config_disabled_checks) { free_string_list(config_disabled_checks); } if (cl_enabled_checks) { free_string_list(cl_enabled_checks); } if (cl_disabled_checks) { free_string_list(cl_disabled_checks); } free_checks(ck); free_file_list(te_files); free_file_list(if_files); free_file_list(fc_files); free_file_list(context_te_files); free_file_list(context_if_files); free_selint_config(&ccd); if (fail_on_finding && found_issue && exit_code == EX_OK) { return EX_DATAERR; } return exit_code; } selint-1.2.1/src/if_checks.h0000644000175100001710000001271014167117255012617 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IF_CHECKS_H #define IF_CHECKS_H #include "check_hooks.h" /********************************************* * Check to make sure all interfaces and templates have a comment above them * Called on NODE_INTERFACE_DEF and NODE_TEMP_DEF nodes. * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue C-004 *********************************************/ struct check_result *check_interface_definitions_have_comment(const struct check_data *data, const struct policy_node *node); /********************************************* * Check that declaration in require blocks are ordered * Called on NODE_REQUIRE and NODE_GEN_REQ nodes. * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue C-006 *********************************************/ struct check_result *check_unordered_declaration_in_require(const struct check_data *data, const struct policy_node *node); /********************************************* * Check that interfaces do not call templates * Called on NODE_IF_CALL nodes * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue S-004 *********************************************/ struct check_result *check_if_calls_template(const struct check_data *data, const struct policy_node *node); /********************************************* * Check that interfaces do contain declarations. * Called on NODE_DECL nodes. * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue S-005 *********************************************/ struct check_result *check_decl_in_if(const struct check_data *data, const struct policy_node *node); /********************************************* * Check that gen_require blocks are quoted * Called on NODE_GEN_REQ nodes * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue S-008 *********************************************/ struct check_result *check_unquoted_gen_require_block(const struct check_data *data, const struct policy_node *node); /********************************************* * Check that all names referenced in interface are listed in its require block * (or declared in that template) * Called on NODE_AV_RULE, NODE_TT_RULE and NODE_IF_CALL nodes. * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue W-002 *********************************************/ struct check_result *check_name_used_but_not_required_in_if(const struct check_data *data, const struct policy_node *node); /********************************************* * Check that all types listed in require block are actually used in the interface * Called on NODE_DECL nodes * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue W-003 *********************************************/ struct check_result *check_name_required_but_not_used_in_if(const struct check_data *data, const struct policy_node *node); /********************************************* * Check that all types listed in require block are declared in the same module * Called on NODE_DECL nodes * data - metadata about the file * node - the node to check * returns NULL if passed or check_result for issue W-011 *********************************************/ struct check_result *check_required_declaration_own(const struct check_data *data, const struct policy_node *node); #endif selint-1.2.1/src/if_checks.c0000644000175100001710000003362214167117255012617 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "if_checks.h" #include "tree.h" #include "maps.h" #include "util.h" #define NOT_REQ_MESSAGE "%s %s is used in interface but not required" struct check_result *check_interface_definitions_have_comment(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { if (node->flavor != NODE_INTERFACE_DEF && node->flavor != NODE_TEMP_DEF) { return alloc_internal_error( "Interface comment check called on non interface definition entry"); } if (!(node->prev) || node->prev->flavor != NODE_COMMENT) { return make_check_result('C', C_ID_IF_COMMENT, "No comment before interface definition for %s", node->data.str); } else { return NULL; } } static int compare_declaration_flavors(enum decl_flavor a, enum decl_flavor b, const struct config_check_data *config) { if (a == b) { return 0; } for (unsigned short i = 0; i < (sizeof config->order_requires / sizeof *config->order_requires); ++i) { if (a == config->order_requires[i]) { return -1; } if (b == config->order_requires[i]) { return 1; } } // should never happen return 0; } static int compare_declarations(const struct declaration_data *a, const struct declaration_data *b, const struct config_check_data *config) { int r = compare_declaration_flavors(a->flavor, b->flavor, config); if (r != 0) { return r; } if (!config->ordering_requires_same_flavor) { // ordering names of the same flavor is disabled in the config file return -1; } // ignore _t suffix, e.g. sort ssh_t before ssh_exec_t const char *a_ptr = a->name; const char *b_ptr = b->name; while (*a_ptr && *b_ptr) { if ((unsigned char)*a_ptr != (unsigned char)*b_ptr) { break; } ++a_ptr; ++b_ptr; } if (*a_ptr == 't' && !*(a_ptr + 1) && a_ptr != a->name && *(a_ptr - 1) == '_') { --a_ptr; } if (*b_ptr == 't' && !*(b_ptr + 1) && b_ptr != b->name && *(b_ptr - 1) == '_') { --b_ptr; } return (unsigned char)*a_ptr - (unsigned char)*b_ptr; } struct check_result *check_unordered_declaration_in_require(const struct check_data *data, const struct policy_node *node) { if (node->flavor != NODE_REQUIRE && node->flavor != NODE_GEN_REQ) { return alloc_internal_error( "Unordered declaration in require check called on non require node"); } const struct policy_node *child = node->first_child; if (!child || child->flavor != NODE_START_BLOCK) { return alloc_internal_error( "No start-block node in require block"); } child = child->next; if (!child) { return make_check_result('C', C_ID_UNORDERED_REQ, "Empty require block"); } const struct declaration_data *prev_decl_data = NULL; for (const struct policy_node *cur = child; cur; cur = cur->next) { if (cur->flavor != NODE_DECL) { return alloc_internal_error( "Non declaration node in require block"); } const struct declaration_data *decl_data = cur->data.d_data; if (prev_decl_data) { const int compare = compare_declarations(prev_decl_data, decl_data, data->config_check_data); if (compare > 0) { return make_check_result('C', C_ID_UNORDERED_REQ, "Unordered declaration in require block (%s %s before %s %s)", decl_flavor_to_string(prev_decl_data->flavor), prev_decl_data->name, decl_flavor_to_string(decl_data->flavor), decl_data->name); } if (compare == 0) { return make_check_result('C', C_ID_UNORDERED_REQ, "Repeated declaration in require block (%s %s)", decl_flavor_to_string(decl_data->flavor), decl_data->name); } } prev_decl_data = decl_data; } return NULL; } struct check_result *check_if_calls_template(const struct check_data *data, const struct policy_node *node) { if (data->flavor != FILE_IF_FILE) { return NULL; } const struct policy_node *parent = node->parent; while (parent && (parent->flavor != NODE_INTERFACE_DEF && parent->flavor != NODE_TEMP_DEF)) { parent = parent->parent; } if (!parent) { return NULL; } const char *call_name = node->data.ic_data->name; if (parent->flavor == NODE_INTERFACE_DEF && look_up_in_template_map(call_name)) { return make_check_result('S', S_ID_IF_CALLS_TEMPL, "interface %s calls template %s", parent->data.str, call_name); } return NULL; } struct check_result *check_decl_in_if(const struct check_data *data, const struct policy_node *node) { if (data->flavor != FILE_IF_FILE) { return NULL; } const struct policy_node *parent = node->parent; while (parent && (parent->flavor != NODE_INTERFACE_DEF && parent->flavor != NODE_TEMP_DEF)) { // ignore declarations in require blocks if (parent->flavor == NODE_GEN_REQ || parent->flavor == NODE_REQUIRE) { return NULL; } parent = parent->parent; } // only check interfaces if (!parent || parent->flavor != NODE_INTERFACE_DEF) { return NULL; } return make_check_result('S', S_ID_DECL_IN_IF, "Declaration of %s in interface", node->data.d_data->name); } struct check_result *check_unquoted_gen_require_block(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { if (node->data.gr_data->unquoted) { return make_check_result('S', S_ID_UNQUOTE_GENREQ, "Gen require block unquoted"); } return NULL; } struct check_result *check_name_used_but_not_required_in_if(const struct check_data *data, const struct policy_node *node) { if (data->flavor != FILE_IF_FILE) { return NULL; } const struct policy_node *cur = node; struct string_list *names_in_current_node = get_names_in_node(node); if (!names_in_current_node) { return NULL; } while (cur) { if (cur->flavor == NODE_INTERFACE_DEF || cur->flavor == NODE_TEMP_DEF) { break; } cur = cur->parent; } if (!cur) { free_string_list(names_in_current_node); return NULL; } // In a template or interface, and cur is a pointer to the definition node cur = cur->first_child; struct string_list *names_required = NULL; struct string_list *names_required_tail = NULL; while (cur && cur != node) { if (cur->flavor == NODE_GEN_REQ || cur->flavor == NODE_REQUIRE) { if (!names_required) { names_required = get_names_required(cur); names_required_tail = names_required; } else { names_required_tail->next = get_names_required(cur); } while (names_required_tail && names_required_tail->next) { names_required_tail = names_required_tail->next; } } cur = dfs_next(cur); // The normal case is that the gen_require block // is at the top level, but it could be nested, // for example in an ifdef } const struct string_list *name_node = names_in_current_node; /* In declarations skip the first name, which is the new declared type */ if (node->flavor == NODE_DECL) { name_node = name_node->next; } const char *flavor = NULL; while (name_node) { if (!str_in_sl(name_node->string, names_required)) { if (0 == strcmp(name_node->string, "system_r")) { // system_r is required by default in all modules // so that is an exception that shouldn't be warned // about. name_node = name_node->next; continue; } if (look_up_in_decl_map(name_node->string, DECL_TYPE)) { flavor = "Type"; } else if (look_up_in_decl_map (name_node->string, DECL_ATTRIBUTE)) { flavor = "Attribute"; } else if (look_up_in_decl_map (name_node->string, DECL_ATTRIBUTE_ROLE)) { flavor = "Role Attribute"; } else if (look_up_in_decl_map (name_node->string, DECL_ROLE)) { flavor = "Role"; } else { // This is a string we don't recognize. Other checks and/or // the compiler catch invalid bare words name_node = name_node->next; continue; } struct check_result *res = make_check_result('W', W_ID_NO_REQ, NOT_REQ_MESSAGE, flavor, name_node->string); free_string_list(names_in_current_node); free_string_list(names_required); return res; } name_node = name_node->next; } free_string_list(names_in_current_node); free_string_list(names_required); return NULL; } struct check_result *check_name_required_but_not_used_in_if(const struct check_data *data, const struct policy_node *node) { if (data->flavor != FILE_IF_FILE) { return NULL; } struct declaration_data *dd = node->data.d_data; const char *flavor = ""; if (dd->flavor == DECL_TYPE) { flavor = "Type"; } else if (dd->flavor == DECL_ATTRIBUTE) { flavor = "Attribute"; } else if (dd->flavor == DECL_ATTRIBUTE_ROLE) { flavor = "Role Attribute"; } else if (dd->flavor == DECL_ROLE) { flavor = "Role"; } else { return NULL; } const struct policy_node *cur = node; const struct policy_node *req_block_node = NULL; while (cur->parent && cur->flavor != NODE_INTERFACE_DEF && cur->flavor != NODE_TEMP_DEF) { if (cur->flavor == NODE_GEN_REQ || cur->flavor == NODE_REQUIRE) { req_block_node = cur; } cur = cur->parent; } if ((cur->flavor != NODE_INTERFACE_DEF && cur->flavor != NODE_TEMP_DEF) || !req_block_node) { // This check only applies to nodes in require blocks in interfaces return NULL; } // ignore interfaces with the ending '_stub'; used in Refpolicy as optional block decider if (cur->flavor == NODE_INTERFACE_DEF && ends_with(cur->data.str, strlen(cur->data.str), "_stub", strlen("_stub"))) { return NULL; } struct string_list *names_to_check = get_names_in_node(node); if (!names_to_check) { // This should never happen return alloc_internal_error( "Declaration with no declared items"); } cur = req_block_node; cur = cur->next; struct string_list *sl_end = NULL; struct string_list *sl_head = NULL; int depth = 0; while (cur) { struct string_list *names_used = get_names_in_node(cur); if (names_used) { if (!sl_head) { sl_head = sl_end = names_used; } else { sl_end->next = names_used; } while (sl_end->next) { sl_end = sl_end->next; } } if (cur->first_child) { cur = cur->first_child; depth++; } else if (cur->next) { cur = cur->next; } else { while (cur->parent && depth > 0) { cur = cur->parent; depth--; if (cur->next) { break; } } cur = cur->next; } } const struct string_list *name_node = names_to_check; struct check_result *res = NULL; while (name_node) { if (!str_in_sl(name_node->string, sl_head)) { res = make_check_result('W', W_ID_UNUSED_REQ, "%s %s is listed in require block but not used in interface", flavor, name_node->string); break; } name_node = name_node->next; } free_string_list(sl_head); free_string_list(names_to_check); return res; } struct check_result *check_required_declaration_own(const struct check_data *data, const struct policy_node *node) { if (data->flavor != FILE_IF_FILE) { return NULL; } const char *name = node->data.d_data->name; const enum decl_flavor flavor = node->data.d_data->flavor; // ignore class, permission and user declarations if (flavor == DECL_CLASS || flavor == DECL_PERM || flavor == DECL_USER) { return NULL; } // TODO: handle templated declarations if (name[0] == '$') { return NULL; } // only check declarations in require blocks if (!is_in_require(node)) { return NULL; } const char *modname_orig_decl = look_up_in_decl_map(name, flavor); if (!modname_orig_decl) { return make_check_result('W', W_ID_IF_DECL_NOT_OWN, "Definition of declared %s %s not found in any module", decl_flavor_to_string(flavor), name); } if (0 == strcmp(modname_orig_decl, data->mod_name)) { return NULL; } // ignore roles declared in kernel module: common in refpolicy if (flavor == DECL_ROLE && 0 == strcmp(modname_orig_decl, "kernel")) { return NULL; } return make_check_result('W', W_ID_IF_DECL_NOT_OWN, "Definition of declared %s %s not found in own module, but in module %s", decl_flavor_to_string(flavor), name, modname_orig_decl); } selint-1.2.1/src/fc_checks.c0000644000175100001710000001661314167117255012612 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "color.h" #include "fc_checks.h" #include "maps.h" #include "tree.h" #include "util.h" #define SETUP_FOR_FC_CHECK(node) \ if (node->flavor != NODE_FC_ENTRY) { \ return alloc_internal_error("File context type check called on non file context entry"); \ } \ const struct fc_entry *entry = node->data.fc_data; \ if (!entry) { \ return alloc_internal_error("Policy node data field is NULL"); \ } \ if (!entry->context) { \ return NULL; \ } \ struct check_result *check_file_context_types_in_mod(const struct check_data *data, const struct policy_node *node) { SETUP_FOR_FC_CHECK(node) if (data->config_check_data->skip_checking_generated_fcs) { // do not check probably generated base and entire filecontext file // do not check probably generated module filecontext files static bool notified = false; if (0 == strcmp("base.fc", data->filename) || 0 == strcmp("all_mods.fc", data->filename) || ends_with(data->filename, strlen(data->filename), ".mod.fc", strlen(".mod.fc"))) { if (!notified) { printf("%sNote%s: Check S-002 is not performed against generated filecontext files (e.g. %s).\n"\ " This can be disabled with the configuration setting \"skip_checking_generated_fcs\".\n", color_note(), color_reset(), data->filename); notified = true; } return NULL; } } const char *type_decl_mod_name = look_up_in_decl_map(entry->context->type, DECL_TYPE); if (!type_decl_mod_name) { // If the type is not in any module, that's a different error // Returning success on an error condition may seem weird, but it is a // redundant condition with another check that will catch this if enabled. // Enabling this check and disabling the undeclared check is a valid // (although strange) configuration which will result in this condition not // being logged, but that is what the user has specifically requested in that // situation. The more common case is having both checks on, and there we // don't want to double log return NULL; } if (strcmp(data->mod_name, type_decl_mod_name)) { return make_check_result('S', S_ID_FC_TYPE, "Type %s is declared in module %s, but used in file context here.", entry->context->type, type_decl_mod_name); } return NULL; } struct check_result *check_gen_context_no_range(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { SETUP_FOR_FC_CHECK(node) if (entry->context->has_gen_context && !entry->context->range) { return make_check_result('S', S_ID_MISSING_RANGE, "No mls levels specified in gen_context"); } return NULL; } struct check_result *check_file_context_regex(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { SETUP_FOR_FC_CHECK(node) const char *path = entry->path; char cur = *path; char prev = '\0'; int error = 0; while (cur != '\0') { char next = *(path + 1); if (cur == '[' && prev != '\\') { // Fast forward through [ ] groups, because regex characters // should not be escaped there while (cur != '\0' && (cur != ']' || prev == '\\')) { next = *(path + 1); prev = cur; cur = next; path++; } continue; } switch (cur) { case '.': // require that periods are either escaped or are one of ".*", ".+", or ".?" // rarely are periods actually used to just mean one of any character if (prev != '\\' && next != '*' && next != '+' && next != '?') { error = 1; } break; case '+': case '*': // require that pluses and asterisks are either escaped or look // something kindof like ".*", "(...)*", or "[...]*" if (prev != '\\' && prev != '.' && prev != ']' && prev != ')') { error = 1; } break; default: break; } if (error) { return make_check_result('W', W_ID_FC_REGEX, "File context path contains a potentially unescaped regex character '%c' at position %d: %s", cur, (int)(path - entry->path + 1), entry->path); } prev = cur; cur = next; path++; } return NULL; } struct check_result *check_file_context_error_nodes(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { if (node->flavor != NODE_ERROR) { return NULL; } return make_check_result('E', E_ID_FC_ERROR, "Bad file context format"); } struct check_result *check_file_context_users(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { SETUP_FOR_FC_CHECK(node) const char *user_decl_filename = look_up_in_decl_map(entry->context->user, DECL_USER); if (!user_decl_filename) { return make_check_result('E', E_ID_FC_USER, "Nonexistent user (%s) listed in fc_entry", entry->context->user); } return NULL; } struct check_result *check_file_context_roles(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { SETUP_FOR_FC_CHECK(node) const char *role_decl_filename = look_up_in_decl_map(entry->context->role, DECL_ROLE); if (!role_decl_filename) { return make_check_result('E', E_ID_FC_ROLE, "Nonexistent role (%s) listed in fc_entry", entry->context->role); } return NULL; } struct check_result *check_file_context_types_exist(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { SETUP_FOR_FC_CHECK(node) const char *type_decl_filename = look_up_in_decl_map(entry->context->type, DECL_TYPE); if (!type_decl_filename) { return make_check_result('E', E_ID_FC_TYPE, "Nonexistent type (%s) listed in fc_entry", entry->context->type); } return NULL; } selint-1.2.1/src/file_list.c0000644000175100001710000000342314167117255012647 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "file_list.h" void file_list_push_back(struct policy_file_list *list, struct policy_file *file) { if (list->tail) { list->tail->next = malloc(sizeof(struct policy_file_node)); list->tail = list->tail->next; } else { list->head = list->tail = malloc(sizeof(struct policy_file_node)); } list->tail->file = file; list->tail->next = NULL; } struct policy_file *make_policy_file(const char *filename, struct policy_node *ast) { struct policy_file *ret = malloc(sizeof(struct policy_file)); ret->filename = strdup(filename); ret->ast = ast; return ret; } int file_name_in_file_list(const char *filename, const struct policy_file_list *list) { const struct policy_file_node *node = list->head; while (node) { if (node->file && 0 == strcmp(filename, node->file->filename)) { return 1; } node = node->next; } return 0; } void free_file_list(struct policy_file_list *to_free) { struct policy_file_node *cur = to_free->head; while (cur) { free(cur->file->filename); free_policy_node(cur->file->ast); free(cur->file); struct policy_file_node *tmp = cur; cur = cur->next; free(tmp); } free(to_free); } selint-1.2.1/src/parse.y0000644000175100001710000007042714167117255012045 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ %define parse.error verbose %locations %define api.pure full %lex-param {yyscan_t scanner} %parse-param {yyscan_t scanner} %code requires { typedef void* yyscan_t; } %{ #include #include #include #include #include "tree.h" #include "parse_functions.h" #include "check_hooks.h" #include "util.h" #include "color.h" #define YYDEBUG 1 struct location { unsigned int first_line; unsigned int first_column; unsigned int last_line; unsigned int last_column; }; #define YYLTYPE struct location %} %union { char *string; char symbol; struct string_list *sl; enum av_rule_flavor av_flavor; enum node_flavor node_flavor; } %{ // local variables and functions static const char *parsing_filename; static struct policy_node *cur; static enum node_flavor expected_node_flavor; static void yyerror(const YYLTYPE *locp, yyscan_t yyscanner, char const *msg); // lexer extern void yyrestart(FILE *input_file , yyscan_t yyscanner); extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner); extern int yylex_init(yyscan_t* scanner); extern int yylex_destroy(yyscan_t scanner); extern char *current_lines[LINES_TO_CACHE]; extern unsigned line_cache_index; extern void reset_current_lines(void); %} %code provides { // number of lines stored, printed on parse errors for multiline statements #define LINES_TO_CACHE 5 // global prototype struct policy_node *yyparse_wrapper(FILE *filefd, const char *filename, enum node_flavor expected_flavor); } %token STRING; %token NUM_STRING; %token IPV4; %token IPV6; %token NUMBER; %token QUOTED_STRING; %token VERSION_NO; %token SELINT_COMMAND; %token UNKNOWN_TOKEN; %token POLICY_MODULE; %token MODULE; %token TYPE; %token TYPEALIAS; %token ALIAS; %token ATTRIBUTE; %token BOOL; %token TYPE_ATTRIBUTE; %token ROLE_ATTRIBUTE; %token ROLE; %token TYPES; %token ATTRIBUTE_ROLE; %token ALLOW; %token ALLOW_XPERM; %token AUDIT_ALLOW; %token AUDIT_ALLOW_XPERM; %token DONT_AUDIT; %token DONT_AUDIT_XPERM; %token NEVER_ALLOW; %token NEVER_ALLOW_XPERM; %token TYPE_TRANSITION; %token TYPE_MEMBER; %token TYPE_CHANGE; %token RANGE_TRANSITION; %token ROLE_TRANSITION; %token OPTIONAL_POLICY; %token GEN_REQUIRE; %token GEN_BOOL; %token GEN_TUNABLE; %token REQUIRE; %token TUNABLE_POLICY; %token IFELSE; %token REFPOLICYWARN; %token CLASS; %token COMMON; %token INHERITS; %token IFDEF; %token IFNDEF; %token IF; %token ELSE; %token GENFSCON; %token SID; %token PORTCON; %token NETIFCON; %token NODECON; %token FS_USE_TRANS; %token FS_USE_XATTR; %token FS_USE_TASK; %token DEFINE; %token GEN_USER; %token GEN_CONTEXT; %token PERMISSIVE; %token TYPEBOUNDS; %token INTERFACE; %token TEMPLATE; %token USERDEBUG_OR_ENG; %token FILE_TYPE_SPECIFIER; %token OPEN_PAREN; %token COMMA; %token PERIOD; %token CLOSE_PAREN; %token OPEN_CURLY; %token CLOSE_CURLY; %token COLON; %token SEMICOLON; %token BACKTICK; %token SINGLE_QUOTE; %token TILDA; %token STAR; %token DASH; %left AND; %left OR; %left XOR; %right NOT; %left EQUAL; %left NOT_EQUAL; %token COMMENT; %type string_list %type comma_string_list %type strings %type xperm_list %type xperm_items %type sl_item %type xperm_item %type arg %type args %type mls_range %type mls_level %type mls_component %type maybe_string_comma %type maybe_selint_disable %type av_type %type xperm_av_type %type if_keyword %destructor { free($$); } %destructor { free_string_list($$); } %% selinux_file: %empty /* empty */ { cur->flavor = NODE_EMPTY; } | te_policy | comments te_policy | if_file | comments if_file | spt_file | comments spt_file | av_file | comments av_file | comments ; // TE File parsing te_policy: header body ; comments: comment | comment comments ; comment: COMMENT { insert_comment(&cur, @$.first_line); } ; maybe_selint_disable: SELINT_COMMAND | %empty { $$ = NULL; } ; header: POLICY_MODULE OPEN_PAREN STRING maybe_header_version CLOSE_PAREN { if (expected_node_flavor != NODE_TE_FILE) { free($3); const struct location loc = { @1.first_line, @1.first_column, @5.last_line, @5.last_column }; yyerror(&loc, NULL, "Error: Unexpected te-file parsed"); YYERROR; } insert_header(&cur, $3, HEADER_MACRO, @$.first_line); free($3); } // Version number isn't needed | MODULE STRING header_version SEMICOLON { if (expected_node_flavor != NODE_TE_FILE) { free($2); const struct location loc = { @1.first_line, @1.first_column, @4.last_line, @4.last_column }; yyerror(&loc, NULL, "Error: Unexpected te-file parsed"); YYERROR; } insert_header(&cur, $2, HEADER_BARE, @$.first_line); free($2); } ; header_version: VERSION_NO { free($1); } | NUMBER { free($1); } ; maybe_header_version: COMMA header_version | %empty ; body: lines ; lines: lines line | line ; line: bare_line maybe_selint_disable { save_command(cur, $2); free($2); } ; bare_line: declaration | type_attribute | role_attribute | type_alias | rule | xperm_rule | role_allow | role_types | type_transition | range_transition | role_transition | interface_call | optional_block | require | m4_call | m4_simple_macro | cond_expr | genfscon | sid | portcon | netifcon | nodecon | fs_use | define | gen_user | permissive | typebounds | SEMICOLON { insert_semicolon(&cur, @$.first_line); } | COMMENT // Would like to do error recovery, but the best strategy seems to be to skip // to next newline, which lex doesn't give us right now. // Also, we would need to know in yyerror whether the error was recoverable | error { const struct location loc = { @1.first_line, @1.first_column, @1.last_line, @1.last_column }; yyerror(&loc, NULL, "Error: Invalid statement"); YYABORT; } ; declaration: type_declaration | ATTRIBUTE STRING SEMICOLON { insert_declaration(&cur, DECL_ATTRIBUTE, $2, NULL, @$.first_line); free($2); } | CLASS STRING string_list SEMICOLON { insert_declaration(&cur, DECL_CLASS, $2, $3, @$.first_line); free($2); } | ROLE STRING SEMICOLON { insert_declaration(&cur, DECL_ROLE, $2, NULL, @$.first_line); free($2); } | ATTRIBUTE_ROLE STRING SEMICOLON { insert_declaration(&cur, DECL_ATTRIBUTE_ROLE, $2, NULL, @$.first_line); free($2); } | bool_declaration ; type_declaration: TYPE STRING SEMICOLON { insert_declaration(&cur, DECL_TYPE, $2, NULL, @$.first_line); free($2); } | TYPE STRING COMMA comma_string_list SEMICOLON { insert_declaration(&cur, DECL_TYPE, $2, $4, @$.first_line); free($2); } | TYPE STRING ALIAS string_list SEMICOLON { insert_declaration(&cur, DECL_TYPE, $2, NULL, @$.first_line); free($2); insert_aliases(&cur, $4, DECL_TYPE, @$.first_line); } | TYPE STRING ALIAS string_list COMMA comma_string_list SEMICOLON { insert_declaration(&cur, DECL_TYPE, $2, $6, @$.first_line); free($2); insert_aliases(&cur, $4, DECL_TYPE, @$.first_line); } ; bool_declaration: BOOL STRING SEMICOLON { insert_declaration(&cur, DECL_BOOL, $2, NULL, @$.first_line); free($2); } | GEN_BOOL OPEN_PAREN STRING COMMA STRING CLOSE_PAREN { insert_declaration(&cur, DECL_BOOL, $3, NULL, @$.first_line); free($3); free($5); } | GEN_TUNABLE OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA STRING CLOSE_PAREN { insert_declaration(&cur, DECL_BOOL, $4, NULL, @$.first_line); free($4); free($7); } | GEN_TUNABLE OPEN_PAREN STRING COMMA STRING CLOSE_PAREN { insert_declaration(&cur, DECL_BOOL, $3, NULL, @$.first_line); free($3); free($5); } ; type_alias: TYPEALIAS STRING ALIAS string_list SEMICOLON { insert_type_alias(&cur, $2, @$.first_line); insert_aliases(&cur, $4, DECL_TYPE, @$.first_line); free($2); } ; type_attribute: TYPE_ATTRIBUTE STRING comma_string_list SEMICOLON { insert_type_attribute(&cur, $2, $3, @$.first_line); free($2); } ; role_attribute: ROLE_ATTRIBUTE STRING comma_string_list SEMICOLON { insert_role_attribute(&cur, $2, $3, @$.first_line); free($2); } rule: av_type string_list string_list COLON string_list string_list SEMICOLON { insert_av_rule(&cur, $1, $2, $3, $5, $6, @$.first_line); } ; av_type: ALLOW { $$ = AV_RULE_ALLOW; } | AUDIT_ALLOW { $$ = AV_RULE_AUDITALLOW; } | DONT_AUDIT { $$ = AV_RULE_DONTAUDIT; } | NEVER_ALLOW { $$ = AV_RULE_NEVERALLOW; } ; xperm_rule: xperm_av_type string_list string_list COLON string_list STRING xperm_list SEMICOLON { insert_xperm_av_rule(&cur, $1, $2, $3, $5, $6, $7, @$.first_line); free($6); } ; xperm_av_type: ALLOW_XPERM { $$ = AV_RULE_ALLOW; } | AUDIT_ALLOW_XPERM { $$ = AV_RULE_AUDITALLOW; } | DONT_AUDIT_XPERM { $$ = AV_RULE_DONTAUDIT; } | NEVER_ALLOW_XPERM { $$ = AV_RULE_NEVERALLOW; } ; xperm_list: OPEN_CURLY xperm_items CLOSE_CURLY { $$ = $2; } | TILDA xperm_list { $$ = sl_from_str("~"); $$->next = $2; } | xperm_item { $$ = sl_from_str_consume($1); } ; xperm_items: xperm_items xperm_item { $$ = concat_string_lists($1, sl_from_str_consume($2)); } | xperm_item { $$ = sl_from_str_consume($1); } | xperm_item DASH xperm_item { $$ = concat_string_lists(sl_from_str_consume($1), concat_string_lists(sl_from_str("-"), sl_from_str_consume($3))); } // TODO: validate usage: enforce two surrounding increasing elements ; xperm_item: STRING | NUM_STRING | NUMBER ; string_list: OPEN_CURLY strings CLOSE_CURLY { $$ = $2; } | TILDA string_list { $$ = sl_from_str("~"); $$->next = $2; } | sl_item { $$ = sl_from_str_consume($1); } | STAR { $$ = sl_from_str("*"); } ; strings: strings sl_item { $$ = concat_string_lists($1, sl_from_str_consume($2)); } | sl_item { $$ = sl_from_str_consume($1); } ; sl_item: STRING | DASH STRING { $$ = malloc(sizeof(char) * (strlen($2) + 2)); $$[0] = '-'; $$[1] = '\0'; strcat($$, $2); free($2);} | QUOTED_STRING ; comma_string_list: comma_string_list COMMA STRING { $$ = concat_string_lists($1, sl_from_str_consume($3)); } | STRING { $$ = sl_from_str_consume($1); } ; role_allow: // It is an error for av_type to be anything other than ALLOW, but specifying ALLOW here is // a grammar conflict, so we leave it general in the parse rule and then check av_type string_list string_list SEMICOLON { if ($1 != AV_RULE_ALLOW) { free_string_list($2); free_string_list($3); const struct location loc = { @1.first_line, @1.first_column, @4.last_line, @4.last_column }; yyerror(&loc, NULL, "Incomplete AV rule"); YYERROR; } insert_role_allow(&cur, $2, $3, @$.first_line); } ; role_types: ROLE STRING TYPES string_list SEMICOLON { insert_role_types(&cur, $2, $4, @$.first_line); free($2); } ; type_transition: TYPE_TRANSITION string_list string_list COLON string_list STRING SEMICOLON { insert_type_transition(&cur, TT_TT, $2, $3, $5, $6, NULL, @$.first_line); free($6); } | TYPE_TRANSITION string_list string_list COLON string_list STRING QUOTED_STRING SEMICOLON { insert_type_transition(&cur, TT_TT, $2, $3, $5, $6, $7, @$.first_line); free($6); free($7); } | TYPE_MEMBER string_list string_list COLON string_list STRING SEMICOLON { insert_type_transition(&cur, TT_TM, $2, $3, $5, $6, NULL, @$.first_line); free($6); } | TYPE_CHANGE string_list string_list COLON string_list STRING SEMICOLON { insert_type_transition(&cur, TT_TC, $2, $3, $5, $6, NULL, @$.first_line); free($6); } ; range_transition: RANGE_TRANSITION string_list string_list COLON string_list mls_range SEMICOLON { insert_type_transition(&cur, TT_RT, $2, $3, $5, $6, NULL, @$.first_line); free($6); } ; role_transition: ROLE_TRANSITION string_list string_list STRING SEMICOLON { insert_role_transition(&cur, $2, $3, NULL, $4, @$.first_line); free($4); } | ROLE_TRANSITION string_list string_list COLON string_list STRING SEMICOLON { insert_role_transition(&cur, $2, $3, $5, $6, @$.first_line); free($6); } ; interface_call: STRING OPEN_PAREN args CLOSE_PAREN { insert_interface_call(&cur, $1, $3, @$.first_line); free($1); } | STRING OPEN_PAREN CLOSE_PAREN { insert_interface_call(&cur, $1, NULL, @$.first_line); free($1); } ; optional_block: optional_open lines SINGLE_QUOTE CLOSE_PAREN { end_optional_policy(&cur); } | optional_open SINGLE_QUOTE CLOSE_PAREN { end_optional_policy(&cur); } | optional_open lines SINGLE_QUOTE COMMA { end_optional_policy(&cur); } BACKTICK { begin_optional_else(&cur, @$.first_line); } lines SINGLE_QUOTE CLOSE_PAREN { end_optional_else(&cur); } ; optional_open: OPTIONAL_POLICY OPEN_PAREN BACKTICK maybe_selint_disable { begin_optional_policy(&cur, @$.first_line); save_command(cur->parent, $4); free($4); } ; require: gen_require_begin BACKTICK maybe_selint_disable require_lines SINGLE_QUOTE CLOSE_PAREN { end_gen_require(&cur, 0); save_command(cur, $3); free($3); } | gen_require_begin require_lines CLOSE_PAREN { end_gen_require(&cur, 1); } | REQUIRE OPEN_CURLY maybe_selint_disable { begin_require(&cur, @$.first_line); save_command(cur->parent, $3); free($3); } require_lines CLOSE_CURLY { end_require(&cur); } ; gen_require_begin: GEN_REQUIRE OPEN_PAREN maybe_selint_disable { begin_gen_require(&cur, @$.first_line); save_command(cur->parent, $3); free($3); } ; require_lines: require_lines require_line | require_line ; require_line: require_bare maybe_selint_disable { save_command(cur, $2); free($2); } ; require_bare: TYPE comma_string_list SEMICOLON { for (const struct string_list *iter = $2; iter; iter = iter->next) insert_declaration(&cur, DECL_TYPE, iter->string, NULL, @$.first_line); free_string_list($2); } | ATTRIBUTE comma_string_list SEMICOLON { for (const struct string_list *iter = $2; iter; iter = iter->next) insert_declaration(&cur, DECL_ATTRIBUTE, iter->string, NULL, @$.first_line); free_string_list($2); } | ROLE comma_string_list SEMICOLON { for (const struct string_list *iter = $2; iter; iter = iter->next) insert_declaration(&cur, DECL_ROLE, iter->string, NULL, @$.first_line); free_string_list($2); } | ATTRIBUTE_ROLE comma_string_list SEMICOLON { for (const struct string_list *iter = $2; iter; iter = iter->next) insert_declaration(&cur, DECL_ATTRIBUTE_ROLE, iter->string, NULL, @$.first_line); free_string_list($2); } | BOOL comma_string_list SEMICOLON { for (const struct string_list *iter = $2; iter; iter = iter->next) insert_declaration(&cur, DECL_BOOL, iter->string, NULL, @$.first_line); free_string_list($2); } | CLASS STRING string_list SEMICOLON { insert_declaration(&cur, DECL_CLASS, $2, $3, @$.first_line); free($2); } | if_or_ifn OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA BACKTICK { begin_ifdef(&cur, @$.first_line); } require_lines SINGLE_QUOTE CLOSE_PAREN { end_ifdef(&cur); free($4); } | if_or_ifn OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA { begin_ifdef(&cur, @$.first_line); } require_lines CLOSE_PAREN { end_ifdef(&cur); free($4); } | COMMENT ; m4_simple_macro: STRING { insert_m4simplemacro(&cur, $1, @$.first_line); } ; m4_call: ifdef | ifelse | refpolicywarn | userdebug_or_eng ; ifdef: if_or_ifn OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA { begin_ifdef(&cur, @$.first_line); } m4_args CLOSE_PAREN { end_ifdef(&cur); free($4); } ; if_or_ifn: IFDEF | IFNDEF ; ifelse: IFELSE OPEN_PAREN { begin_ifelse(&cur, @$.first_line); } m4_args CLOSE_PAREN { end_ifelse(&cur); } ; refpolicywarn: REFPOLICYWARN OPEN_PAREN BACKTICK arbitrary_m4_string SINGLE_QUOTE CLOSE_PAREN ; userdebug_or_eng: USERDEBUG_OR_ENG OPEN_PAREN BACKTICK lines SINGLE_QUOTE CLOSE_PAREN ; arbitrary_m4_string: m4_string_elem | m4_string_elem arbitrary_m4_string | BACKTICK m4_string_elem SINGLE_QUOTE ; m4_string_elem: STRING { free($1); } | OPEN_PAREN | CLOSE_PAREN | OPEN_CURLY | CLOSE_CURLY | COMMA | PERIOD | COLON | SEMICOLON | DASH ; condition: STRING { free($1); } | NOT condition | condition AND condition | condition OR condition | condition XOR condition | condition EQUAL condition | condition NOT_EQUAL condition | OPEN_PAREN condition CLOSE_PAREN ; m4_args: { begin_m4_argument(&cur, @$.first_line); } m4_argument { end_m4_argument(&cur); } | m4_args COMMA { begin_m4_argument(&cur, @$.first_line); } m4_argument { end_m4_argument(&cur); } ; m4_argument: %empty | BACKTICK SINGLE_QUOTE | BACKTICK lines SINGLE_QUOTE | STRING { free($1); } ; arg: xperm_list | QUOTED_STRING { $$ = sl_from_str_consume($1); } | BACKTICK mls_range SINGLE_QUOTE { $$ = sl_from_str_consume($2); } | BACKTICK SINGLE_QUOTE { $$ = sl_from_str(""); } ; args: arg | args COMMA arg { $$ = concat_string_lists($1, $3); } | args sl_item { struct string_list *sl = calloc(1, sizeof(struct string_list)); sl->string = $2; sl->has_incorrect_space = 1; $$ = concat_string_lists($1, sl); } ; mls_range: mls_level DASH mls_level { size_t len = strlen($1) + strlen($3) + 1 /* DASH */ + 1 /* NT */; $$ = malloc(len); snprintf($$, len, "%s-%s", $1, $3); free($1); free($3); } | mls_level ; mls_level: mls_component | mls_component COLON mls_component { size_t len = strlen($1) + strlen($3) + 1 /* COLON */ + 1 /* NT */; $$ = malloc(len); snprintf($$, len, "%s:%s", $1, $3); free($1); free($3); } ; mls_component: STRING | STRING PERIOD STRING { size_t len = strlen($1) + strlen($3) + 1 /* PERIOD */ + 1 /* NT */; $$ = malloc(len); snprintf($$, len, "%s.%s", $1, $3); free($1); free($3); } ; cond_expr: tunable_block | boolean_block ; boolean_block: boolean_open condition CLOSE_PAREN OPEN_CURLY lines CLOSE_CURLY { end_boolean_policy(&cur); } | boolean_open condition CLOSE_PAREN OPEN_CURLY lines CLOSE_CURLY ELSE OPEN_CURLY lines CLOSE_CURLY { end_boolean_policy(&cur); } ; boolean_open: IF OPEN_PAREN maybe_selint_disable { begin_boolean_policy(&cur, @$.first_line); save_command(cur->parent, $3); free($3); } ; tunable_block: TUNABLE_POLICY OPEN_PAREN BACKTICK { begin_tunable_policy(&cur, @$.first_line); } condition SINGLE_QUOTE COMMA m4_args CLOSE_PAREN { end_tunable_policy(&cur); } | TUNABLE_POLICY OPEN_PAREN { begin_tunable_policy(&cur, @$.first_line); } condition COMMA m4_args CLOSE_PAREN { end_tunable_policy(&cur); } ; genfscon: GENFSCON STRING STRING genfscon_context { free($2); free($3); } | GENFSCON NUM_STRING STRING genfscon_context { free($2); free($3); } ; genfscon_context: context | FILE_TYPE_SPECIFIER context ; sid: SID STRING context { free($2); } ; portcon: PORTCON STRING port_range context { free($2); } ; port_range: NUM_STRING { free($1); } | NUMBER { free($1); } | // TODO: This only happens with whitespace around the dash. NUM_STRING catches "1000-1001" type // names. Is that actually a valid scenario? NUMBER DASH NUMBER { free($1); free($3); } ; netifcon: NETIFCON STRING context context { free($2); } ; nodecon: NODECON two_ip_addrs context ; two_ip_addrs: IPV4 IPV4 { free($1); free($2); } | IPV6 IPV6 { free($1); free($2); } ; fs_use: FS_USE_TRANS STRING context SEMICOLON { free($2); } | FS_USE_XATTR STRING context SEMICOLON { free($2); } | FS_USE_TASK STRING context SEMICOLON { free($2); } ; define: DEFINE OPEN_PAREN { begin_define(&cur, @$.first_line); } define_name define_content CLOSE_PAREN { end_define(&cur); } ; define_name: BACKTICK STRING SINGLE_QUOTE { free($2); } | STRING { free($1); } ; define_content: %empty | COMMA define_expansion ; define_expansion: %empty | BACKTICK arbitrary_m4_string SINGLE_QUOTE | STRING { free($1); } ; maybe_string_comma: STRING COMMA | COMMA { $$ = strdup(""); } ; gen_user: GEN_USER OPEN_PAREN maybe_string_comma maybe_string_comma strings COMMA mls_range COMMA mls_range CLOSE_PAREN { free($3); free($4); free_string_list($5); free($7); free($9); } | GEN_USER OPEN_PAREN maybe_string_comma maybe_string_comma strings COMMA mls_range COMMA mls_range COMMA mls_range CLOSE_PAREN { free($3); free($4); free_string_list($5); free($7); free($9); free($11); } ; context: raw_context | GEN_CONTEXT OPEN_PAREN raw_context CLOSE_PAREN | GEN_CONTEXT OPEN_PAREN raw_context COMMA mls_range CLOSE_PAREN { free($5); } | GEN_CONTEXT OPEN_PAREN raw_context COMMA mls_range COMMA mls_range CLOSE_PAREN { free($5); free($7); } | GEN_CONTEXT OPEN_PAREN raw_context COMMA mls_range COMMA CLOSE_PAREN { free($5); } ; raw_context: STRING COLON STRING COLON STRING { free($1); free($3); free($5); } | STRING COLON STRING COLON STRING COLON mls_range { free($1); free($3); free($5); free($7); } ; permissive: PERMISSIVE STRING SEMICOLON { insert_permissive_statement(&cur, $2, @$.first_line); free($2);} ; typebounds: TYPEBOUNDS STRING STRING SEMICOLON { free($2); free($3); } ; // IF File parsing if_file: interface_def if_lines | interface_def //| // Empty file //EOF ; if_lines: if_lines if_line | if_line ; if_line: interface_def | COMMENT { insert_comment(&cur, @$.first_line); } ; interface_def: start_interface maybe_selint_disable lines end_interface { save_command(cur, $2); free($2); } | start_interface maybe_selint_disable end_interface { save_command(cur, $2); free($2); } ; start_interface: if_keyword OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA BACKTICK { if (expected_node_flavor != NODE_IF_FILE) { const struct location loc = { @1.first_line, @1.first_column, @7.last_line, @7.last_column }; yyerror(&loc, NULL, "Error: Unexpected if-file parsed"); YYERROR; } begin_interface_def(&cur, $1, $4, @$.first_line); free($4); } ; end_interface: SINGLE_QUOTE CLOSE_PAREN { end_interface_def(&cur); } ; if_keyword: INTERFACE { $$ = NODE_INTERFACE_DEF; } | TEMPLATE { $$ = NODE_TEMP_DEF; } ; // spt file parsing spt_file: support_def spt_lines | support_def ; spt_lines: spt_lines spt_line | spt_line ; spt_line: support_def | COMMENT ; support_def: DEFINE OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA BACKTICK string_list SINGLE_QUOTE CLOSE_PAREN { if (expected_node_flavor != NODE_SPT_FILE) { free($4); free_string_list($8); const struct location loc = { @1.first_line, @1.first_column, @10.last_line, @10.last_column }; yyerror(&loc, NULL, "Error: Unexpected spt-file parsed"); YYERROR; } if (ends_with($4, strlen($4), "_perms", strlen("_perms"))) { insert_into_permmacros_map($4, $8); } else { free_string_list($8); } free($4); } | DEFINE OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA BACKTICK string_list refpolicywarn SINGLE_QUOTE CLOSE_PAREN { if (expected_node_flavor != NODE_SPT_FILE) { free($4); free_string_list($8); const struct location loc = { @1.first_line, @1.first_column, @11.last_line, @11.last_column }; yyerror(&loc, NULL, "Error: Unexpected spt-file parsed"); YYERROR; } free($4); free_string_list($8); } // do not import ; // access-vector file av_file: // must not allow a comment to be first -> parser conflict av_definition av_contents | av_definition ; av_contents: av_contents av_content | av_content ; av_content: av_definition | COMMENT ; av_definition: av_class_definition | av_common_definition ; av_class_definition: CLASS STRING av_permission_list { if (expected_node_flavor != NODE_AV_FILE) { free($2); const struct location loc = { @1.first_line, @1.first_column, @3.last_line, @3.last_column }; yyerror(&loc, NULL, "Error: Unexpected av-file parsed"); YYERROR; } insert_into_decl_map($2, "__av_file__", DECL_CLASS); free($2); } | CLASS STRING INHERITS STRING { if (expected_node_flavor != NODE_AV_FILE) { free($2); free($4); const struct location loc = { @1.first_line, @1.first_column, @4.last_line, @4.last_column }; yyerror(&loc, NULL, "Error: Unexpected av-file parsed"); YYERROR; } insert_into_decl_map($2, "__av_file__", DECL_CLASS); free($2); free($4); } | CLASS STRING INHERITS STRING av_permission_list { if (expected_node_flavor != NODE_AV_FILE) { free($2); free($4); const struct location loc = { @1.first_line, @1.first_column, @5.last_line, @5.last_column }; yyerror(&loc, NULL, "Error: Unexpected av-file parsed"); YYERROR; } insert_into_decl_map($2, "__av_file__", DECL_CLASS); free($2); free($4); } ; av_common_definition: COMMON STRING av_permission_list { free($2); } ; av_permission_list: OPEN_CURLY av_permissions CLOSE_CURLY ; av_permissions: av_permissions av_permission | av_permission ; av_permission: STRING { insert_into_decl_map($1, "__av_file__", DECL_PERM); free($1); } | COMMENT ; %% static unsigned leading_spaces(const char *str) { unsigned result = 0; while (str[result] == ' ' || str[result] == '\t') result++; return result; } static void yyerror(const YYLTYPE *locp, __attribute__((unused)) yyscan_t scanner, char const *msg) { // Print error tag: """test7.if: 1: (F): Error: Unexpected te-file parsed (F-001)""" { struct check_result *res = make_check_result('F', F_ID_POLICY_SYNTAX, "%s", msg); res->lineno = locp->first_line; struct check_data data; data.mod_name = get_current_module_name(); char *copy = strdup(parsing_filename); data.filename = basename(copy); data.flavor = FILE_TE_FILE; // We don't know but it's unused by display_check_result display_check_result(res, &data); free(copy); free_check_result(res); } unsigned lines_to_print = locp->last_line - locp->first_line + 1; bool shortened = false; if (lines_to_print > LINES_TO_CACHE) { lines_to_print = LINES_TO_CACHE; shortened = true; printf("%5u | ... [truncated]\n", locp->last_line - LINES_TO_CACHE); } for (unsigned k = lines_to_print; k > 0; --k) { const char *current_line = trim_right(current_lines[(LINES_TO_CACHE + line_cache_index - k + 1) % LINES_TO_CACHE]); const unsigned current_first_column = (k == lines_to_print && !shortened) ? locp->first_column : (1 + leading_spaces(current_line)); const unsigned current_last_column = (k == 1) ? locp->last_column : (unsigned)strlen(current_line); printf("%5u |", locp->last_line - (k - 1)); // print line, replace tabs unsigned tabs_before_hinter = 0, tabs_inside_hinter = 0; if (*current_line != '\0') { printf(" "); } for (const char *c = current_line; *c != '\0'; ++c) { if (*c == '\t') { if ((size_t)(c - current_line) < current_first_column) { tabs_before_hinter++; } else if ((size_t)(c - current_line) < current_last_column) { tabs_inside_hinter++; } printf(" "); continue; } if (!isprint((unsigned char)*c) && !isspace((unsigned char)*c)) { printf("%s!%s\n%sWarning%s: Line in question contains unprintable character at position %zu: 0x%.2x\n", color_error(), color_reset(), color_warning(), color_reset(), (size_t)(c - current_line + 1), *c); return; } printf("%c", *c); } printf("\n | "); // print hinter for (unsigned i = 0; i < tabs_before_hinter; ++i) { printf(" "); } for (unsigned i = tabs_before_hinter + 1; i < current_first_column; ++i) { printf(" "); } if (k == lines_to_print) { printf("%s^", color_error()); } else { printf("%s~", color_error()); } if (current_last_column > current_first_column) { for (unsigned i = 0; i < (current_last_column - current_first_column); ++i) { printf("~"); } for (unsigned i = 0; i < tabs_inside_hinter; ++i) { printf("~~~"); } } printf("%s\n", color_reset()); } } struct policy_node *yyparse_wrapper(FILE *filefd, const char *filename, enum node_flavor expected_flavor) { struct policy_node *ast = calloc(1, sizeof(struct policy_node)); ast->flavor = expected_node_flavor = expected_flavor; yyscan_t scanner; yylex_init(&scanner); yyrestart(filefd, scanner); parsing_filename = filename; cur = ast; const int ret = yyparse(scanner); reset_current_lines(); yylex_destroy(scanner); if (ret != 0) { // parser will have printed an error message free_policy_node(ast); return NULL; } return ast; } selint-1.2.1/src/runner.c0000644000175100001710000003550314167117255012212 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "color.h" #include "runner.h" #include "fc_checks.h" #include "if_checks.h" #include "te_checks.h" #include "parse_fc.h" #include "parse.h" #include "util.h" #include "startup.h" #define CHECK_ENABLED(cid) is_check_enabled(cid, config_enabled_checks, config_disabled_checks, cl_enabled_checks, cl_disabled_checks, only_enabled) struct policy_node *parse_one_file(const char *filename, enum node_flavor flavor) { char *copy = strdup(filename); char *mod_name = basename(copy); mod_name[strlen(mod_name) - 3] = '\0'; // Remove suffix set_current_module_name(mod_name); free(copy); FILE *f = fopen(filename, "r"); if (!f) { printf("%sError%s: Failed to open %s: %s\n", color_error(), color_reset(), filename, strerror(errno)); return NULL; } struct policy_node *ast = yyparse_wrapper(f, filename, flavor); fclose(f); // dont run cleanup_parsing until everything is done because it frees the maps return ast; } int is_check_enabled(const char *check_name, const struct string_list *config_enabled_checks, const struct string_list *config_disabled_checks, const struct string_list *cl_enabled_checks, const struct string_list *cl_disabled_checks, int only_enabled) { int is_enabled = 1; // default to enabled if (only_enabled) { // if only_enabled is true, we only want to enable checks that are // explicitly enabled in the cl_enabled_checks. So change the default // enabled state to disabled, and skip all other checks except for the // enabled checks. is_enabled = 0; } else { if (str_in_sl(check_name, config_disabled_checks)) { is_enabled = 0; } if (str_in_sl(check_name, config_enabled_checks)) { is_enabled = 1; } if (str_in_sl(check_name, cl_disabled_checks)) { is_enabled = 0; } } if (str_in_sl(check_name, cl_enabled_checks)) { is_enabled = 1; } return is_enabled; } struct checks *register_checks(char level, const struct string_list *config_enabled_checks, const struct string_list *config_disabled_checks, const struct string_list *cl_enabled_checks, const struct string_list *cl_disabled_checks, int only_enabled) { struct checks *ck = malloc(sizeof(struct checks)); memset(ck, 0, sizeof(struct checks)); switch (level) { case 'C': if (CHECK_ENABLED("C-001")) { add_check(NODE_TE_FILE, ck, "C-001", check_te_order); add_check(NODE_DECL, ck, "C-001", check_te_order); add_check(NODE_AV_RULE, ck, "C-001", check_te_order); add_check(NODE_XAV_RULE, ck, "C-001", check_te_order); add_check(NODE_IF_CALL, ck, "C-001", check_te_order); add_check(NODE_TT_RULE, ck, "C-001", check_te_order); add_check(NODE_CLEANUP, ck, "C-001", check_te_order); } if (CHECK_ENABLED("C-004")) { add_check(NODE_INTERFACE_DEF, ck, "C-004", check_interface_definitions_have_comment); add_check(NODE_TEMP_DEF, ck, "C-004", check_interface_definitions_have_comment); } if (CHECK_ENABLED("C-005")) { add_check(NODE_AV_RULE, ck, "C-005", check_unordered_perms); add_check(NODE_XAV_RULE, ck, "C-005", check_unordered_perms); add_check(NODE_DECL, ck, "C-005", check_unordered_perms); } if (CHECK_ENABLED("C-006")) { add_check(NODE_REQUIRE, ck, "C-006", check_unordered_declaration_in_require); add_check(NODE_GEN_REQ, ck, "C-006", check_unordered_declaration_in_require); } if (CHECK_ENABLED("C-007")) { add_check(NODE_AV_RULE, ck, "C-007", check_no_self); add_check(NODE_XAV_RULE, ck, "C-007", check_no_self); } // FALLTHRU case 'S': if (CHECK_ENABLED("S-001")) { add_check(NODE_REQUIRE, ck, "S-001", check_require_block); add_check(NODE_GEN_REQ, ck, "S-001", check_require_block); } if (CHECK_ENABLED("S-002")) { add_check(NODE_FC_ENTRY, ck, "S-002", check_file_context_types_in_mod); } if (CHECK_ENABLED("S-003")) { add_check(NODE_SEMICOLON, ck, "S-003", check_useless_semicolon); } if (CHECK_ENABLED("S-004")) { add_check(NODE_IF_CALL, ck, "S-004", check_if_calls_template); } if (CHECK_ENABLED("S-005")) { add_check(NODE_DECL, ck, "S-005", check_decl_in_if); } if (CHECK_ENABLED("S-006")) { add_check(NODE_HEADER, ck, "S-006", check_bare_module_statement); } if (CHECK_ENABLED("S-007")) { add_check(NODE_FC_ENTRY, ck, "S-007", check_gen_context_no_range); } if (CHECK_ENABLED("S-008")) { add_check(NODE_GEN_REQ, ck, "S-008", check_unquoted_gen_require_block); } if (CHECK_ENABLED("S-009")) { add_check(NODE_AV_RULE, ck, "S-009", check_perm_macro_class_mismatch); } if (CHECK_ENABLED("S-010")) { add_check(NODE_AV_RULE, ck, "S-010", check_perm_macro_available); } // FALLTHRU case 'W': if (CHECK_ENABLED("W-001")) { add_check(NODE_AV_RULE, ck, "W-001", check_no_explicit_declaration); add_check(NODE_XAV_RULE, ck, "W-001", check_no_explicit_declaration); add_check(NODE_IF_CALL, ck, "W-001", check_no_explicit_declaration); add_check(NODE_TT_RULE, ck, "W-001", check_no_explicit_declaration); add_check(NODE_RT_RULE, ck, "W-001", check_no_explicit_declaration); add_check(NODE_ROLE_ALLOW, ck, "W-001", check_no_explicit_declaration); add_check(NODE_ROLE_TYPES, ck, "W-001", check_no_explicit_declaration); add_check(NODE_ALIAS, ck, "W-001", check_no_explicit_declaration); add_check(NODE_TYPE_ALIAS, ck, "W-001", check_no_explicit_declaration); add_check(NODE_TYPE_ATTRIBUTE, ck, "W-001", check_no_explicit_declaration); add_check(NODE_ROLE_ATTRIBUTE, ck, "W-001", check_no_explicit_declaration); add_check(NODE_PERMISSIVE, ck, "W-001", check_no_explicit_declaration); add_check(NODE_DECL, ck, "W-001", check_no_explicit_declaration); } if (CHECK_ENABLED("W-002")) { add_check(NODE_AV_RULE, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_XAV_RULE, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_IF_CALL, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_TT_RULE, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_RT_RULE, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_ROLE_ALLOW, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_ROLE_TYPES, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_ALIAS, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_TYPE_ALIAS, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_TYPE_ATTRIBUTE, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_ROLE_ATTRIBUTE, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_PERMISSIVE, ck, "W-002", check_name_used_but_not_required_in_if); add_check(NODE_DECL, ck, "W-002", check_name_used_but_not_required_in_if); } if (CHECK_ENABLED("W-003")) { add_check(NODE_DECL, ck, "W-003", check_name_required_but_not_used_in_if); } if (CHECK_ENABLED("W-004")) { add_check(NODE_FC_ENTRY, ck, "W-004", check_file_context_regex); } if (CHECK_ENABLED("W-005")) { add_check(NODE_IF_CALL, ck, "W-005", check_module_if_call_in_optional); } if (CHECK_ENABLED("W-006")) { add_check(NODE_IF_CALL, ck, "W-006", check_empty_if_call_arg); } if (CHECK_ENABLED("W-007")) { add_check(NODE_IF_CALL, ck, "W-007", check_space_if_call_arg); } if (CHECK_ENABLED("W-008")) { add_check(NODE_AV_RULE, ck, "W-008", check_risky_allow_perm); } if (CHECK_ENABLED("W-009")) { add_check(NODE_HEADER, ck, "W-009", check_module_file_name_mismatch); } if (CHECK_ENABLED("W-010")) { add_check(NODE_IF_CALL, ck, "W-010", check_unknown_interface_call); } if (CHECK_ENABLED("W-011")) { add_check(NODE_DECL, ck, "W-011", check_required_declaration_own); } // FALLTHRU case 'E': if (CHECK_ENABLED("E-002")) { add_check(NODE_ERROR, ck, "E-002", check_file_context_error_nodes); } if (CHECK_ENABLED("E-003")) { add_check(NODE_FC_ENTRY, ck, "E-003", check_file_context_users); } if (CHECK_ENABLED("E-004")) { add_check(NODE_FC_ENTRY, ck, "E-004", check_file_context_roles); } if (CHECK_ENABLED("E-005")) { add_check(NODE_FC_ENTRY, ck, "E-005", check_file_context_types_exist); } if (CHECK_ENABLED("E-006")) { add_check(NODE_DECL, ck, "E-006", check_declaration_interface_nameclash); } if (CHECK_ENABLED("E-007") && check_unknown_permission_condition()) { add_check(NODE_AV_RULE, ck, "E-007", check_unknown_permission); } if (CHECK_ENABLED("E-008") && check_unknown_class_condition()) { add_check(NODE_AV_RULE, ck, "E-008", check_unknown_class); add_check(NODE_RT_RULE, ck, "E-008", check_unknown_class); add_check(NODE_TT_RULE, ck, "E-008", check_unknown_class); } if (CHECK_ENABLED("E-009")) { add_check(NODE_OPTIONAL_POLICY, ck, "E-009", check_empty_block); add_check(NODE_GEN_REQ, ck, "E-009", check_empty_block); add_check(NODE_REQUIRE, ck, "E-009", check_empty_block); } if (CHECK_ENABLED("E-010")) { add_check(NODE_M4_SIMPLE_MACRO, ck, "E-010", check_stray_word); } case 'F': break; default: free(ck); return NULL; } return ck; } enum selint_error parse_all_files_in_list(struct policy_file_list *files, enum node_flavor flavor) { struct policy_file_node *current = files->head; while (current) { print_if_verbose("Parsing %s\n", current->file->filename); current->file->ast = parse_one_file(current->file->filename, flavor); if (!current->file->ast) { return SELINT_PARSE_ERROR; } current = current->next; } return SELINT_SUCCESS; } enum selint_error parse_all_fc_files_in_list(struct policy_file_list *files, const struct string_list *custom_fc_macros) { struct policy_file_node *current = files->head; while (current) { print_if_verbose("Parsing fc file %s\n", current->file->filename); current->file->ast = parse_fc_file(current->file->filename, custom_fc_macros); if (!current->file->ast) { return SELINT_PARSE_ERROR; } current = current->next; } return SELINT_SUCCESS; } enum selint_error run_checks_on_one_file(struct checks *ck, const struct check_data *data, const struct policy_node *head) { const struct policy_node *current = head; while (current) { enum selint_error res = call_checks(ck, data, current); if (res != SELINT_SUCCESS) { return res; } current = dfs_next(current); } // Give checks a change to clean up state struct policy_node cleanup; memset(&cleanup, 0, sizeof(struct policy_node)); cleanup.flavor = NODE_CLEANUP; return call_checks(ck, data, &cleanup); } enum selint_error run_all_checks(struct checks *ck, enum file_flavor flavor, struct policy_file_list *files, const struct config_check_data *ccd) { struct policy_file_node *file = files->head; struct check_data data; data.flavor = flavor; while (file) { { char *copy = strdup(file->file->filename); data.filename = strdup(basename(copy)); free(copy); } data.mod_name = strdup(data.filename); data.config_check_data = ccd; char *suffix_ptr = strrchr(data.mod_name, '.'); *suffix_ptr = '\0'; enum selint_error res = run_checks_on_one_file(ck, &data, file->file->ast); if (res != SELINT_SUCCESS) { return res; } free(data.filename); free(data.mod_name); file = file->next; } return SELINT_SUCCESS; } enum selint_error run_analysis(struct checks *ck, struct policy_file_list *te_files, struct policy_file_list *if_files, struct policy_file_list *fc_files, struct policy_file_list *context_te_files, struct policy_file_list *context_if_files, const struct string_list *custom_fc_macros, const struct config_check_data *ccd) { enum selint_error res; res = parse_all_files_in_list(if_files, NODE_IF_FILE); if (res != SELINT_SUCCESS) { goto out; } // We parse all the context files for the side effects of parsing (populating // the hash tables), and to mark the transform interfaces. Then we only // run checks on the non-context files res = parse_all_files_in_list(context_if_files, NODE_IF_FILE); if (res != SELINT_SUCCESS) { goto out; } // Make temporary joined list to mark ALL transform interfaces struct policy_file_list *all_if_files = calloc(1, sizeof(struct policy_file_list)); if (if_files->tail) { // Only concatenate if if_files contains files all_if_files->head = if_files->head; if_files->tail->next = context_if_files->head; } else { // If both are empty, just having an empty list is fine all_if_files->head = context_if_files->head; } all_if_files->tail = context_if_files->tail; mark_transform_interfaces(all_if_files); // Restore if (if_files->tail) { if_files->tail->next = NULL; } free(all_if_files); res = parse_all_files_in_list(context_te_files, NODE_TE_FILE); if (res != SELINT_SUCCESS) { goto out; } res = parse_all_files_in_list(te_files, NODE_TE_FILE); if (res != SELINT_SUCCESS) { goto out; } res = parse_all_fc_files_in_list(fc_files, custom_fc_macros); if (res != SELINT_SUCCESS) { goto out; } res = run_all_checks(ck, FILE_TE_FILE, te_files, ccd); if (res != SELINT_SUCCESS) { goto out; } res = run_all_checks(ck, FILE_IF_FILE, if_files, ccd); if (res != SELINT_SUCCESS) { goto out; } res = run_all_checks(ck, FILE_FC_FILE, fc_files, ccd); if (res != SELINT_SUCCESS) { goto out; } out: cleanup_parsing(); return res; } void display_run_summary(const struct checks *ck) { printf("Found the following issue counts:\n"); display_check_issue_counts(ck); } selint-1.2.1/src/parse.c0000644000175100001710000041675214167117371012023 00000000000000/* A Bison parser, made by GNU Bison 3.5.1. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Undocumented macros, especially those whose name start with YY_, are private implementation details. Do not rely on them. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.5.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 2 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* First part of user prologue. */ #line 27 "parse.y" #include #include #include #include #include "tree.h" #include "parse_functions.h" #include "check_hooks.h" #include "util.h" #include "color.h" #define YYDEBUG 1 struct location { unsigned int first_line; unsigned int first_column; unsigned int last_line; unsigned int last_column; }; #define YYLTYPE struct location #line 93 "parse.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 1 #endif /* Use api.header.include to #include this header instead of duplicating it here. */ #ifndef YY_YY_PARSE_H_INCLUDED # define YY_YY_PARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* "%code requires" blocks. */ #line 23 "parse.y" typedef void* yyscan_t; #line 140 "parse.c" /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { STRING = 258, NUM_STRING = 259, IPV4 = 260, IPV6 = 261, NUMBER = 262, QUOTED_STRING = 263, VERSION_NO = 264, SELINT_COMMAND = 265, UNKNOWN_TOKEN = 266, POLICY_MODULE = 267, MODULE = 268, TYPE = 269, TYPEALIAS = 270, ALIAS = 271, ATTRIBUTE = 272, BOOL = 273, TYPE_ATTRIBUTE = 274, ROLE_ATTRIBUTE = 275, ROLE = 276, TYPES = 277, ATTRIBUTE_ROLE = 278, ALLOW = 279, ALLOW_XPERM = 280, AUDIT_ALLOW = 281, AUDIT_ALLOW_XPERM = 282, DONT_AUDIT = 283, DONT_AUDIT_XPERM = 284, NEVER_ALLOW = 285, NEVER_ALLOW_XPERM = 286, TYPE_TRANSITION = 287, TYPE_MEMBER = 288, TYPE_CHANGE = 289, RANGE_TRANSITION = 290, ROLE_TRANSITION = 291, OPTIONAL_POLICY = 292, GEN_REQUIRE = 293, GEN_BOOL = 294, GEN_TUNABLE = 295, REQUIRE = 296, TUNABLE_POLICY = 297, IFELSE = 298, REFPOLICYWARN = 299, CLASS = 300, COMMON = 301, INHERITS = 302, IFDEF = 303, IFNDEF = 304, IF = 305, ELSE = 306, GENFSCON = 307, SID = 308, PORTCON = 309, NETIFCON = 310, NODECON = 311, FS_USE_TRANS = 312, FS_USE_XATTR = 313, FS_USE_TASK = 314, DEFINE = 315, GEN_USER = 316, GEN_CONTEXT = 317, PERMISSIVE = 318, TYPEBOUNDS = 319, INTERFACE = 320, TEMPLATE = 321, USERDEBUG_OR_ENG = 322, FILE_TYPE_SPECIFIER = 323, OPEN_PAREN = 324, COMMA = 325, PERIOD = 326, CLOSE_PAREN = 327, OPEN_CURLY = 328, CLOSE_CURLY = 329, COLON = 330, SEMICOLON = 331, BACKTICK = 332, SINGLE_QUOTE = 333, TILDA = 334, STAR = 335, DASH = 336, AND = 337, OR = 338, XOR = 339, NOT = 340, EQUAL = 341, NOT_EQUAL = 342, COMMENT = 343 }; #endif /* Tokens. */ #define STRING 258 #define NUM_STRING 259 #define IPV4 260 #define IPV6 261 #define NUMBER 262 #define QUOTED_STRING 263 #define VERSION_NO 264 #define SELINT_COMMAND 265 #define UNKNOWN_TOKEN 266 #define POLICY_MODULE 267 #define MODULE 268 #define TYPE 269 #define TYPEALIAS 270 #define ALIAS 271 #define ATTRIBUTE 272 #define BOOL 273 #define TYPE_ATTRIBUTE 274 #define ROLE_ATTRIBUTE 275 #define ROLE 276 #define TYPES 277 #define ATTRIBUTE_ROLE 278 #define ALLOW 279 #define ALLOW_XPERM 280 #define AUDIT_ALLOW 281 #define AUDIT_ALLOW_XPERM 282 #define DONT_AUDIT 283 #define DONT_AUDIT_XPERM 284 #define NEVER_ALLOW 285 #define NEVER_ALLOW_XPERM 286 #define TYPE_TRANSITION 287 #define TYPE_MEMBER 288 #define TYPE_CHANGE 289 #define RANGE_TRANSITION 290 #define ROLE_TRANSITION 291 #define OPTIONAL_POLICY 292 #define GEN_REQUIRE 293 #define GEN_BOOL 294 #define GEN_TUNABLE 295 #define REQUIRE 296 #define TUNABLE_POLICY 297 #define IFELSE 298 #define REFPOLICYWARN 299 #define CLASS 300 #define COMMON 301 #define INHERITS 302 #define IFDEF 303 #define IFNDEF 304 #define IF 305 #define ELSE 306 #define GENFSCON 307 #define SID 308 #define PORTCON 309 #define NETIFCON 310 #define NODECON 311 #define FS_USE_TRANS 312 #define FS_USE_XATTR 313 #define FS_USE_TASK 314 #define DEFINE 315 #define GEN_USER 316 #define GEN_CONTEXT 317 #define PERMISSIVE 318 #define TYPEBOUNDS 319 #define INTERFACE 320 #define TEMPLATE 321 #define USERDEBUG_OR_ENG 322 #define FILE_TYPE_SPECIFIER 323 #define OPEN_PAREN 324 #define COMMA 325 #define PERIOD 326 #define CLOSE_PAREN 327 #define OPEN_CURLY 328 #define CLOSE_CURLY 329 #define COLON 330 #define SEMICOLON 331 #define BACKTICK 332 #define SINGLE_QUOTE 333 #define TILDA 334 #define STAR 335 #define DASH 336 #define AND 337 #define OR 338 #define XOR 339 #define NOT 340 #define EQUAL 341 #define NOT_EQUAL 342 #define COMMENT 343 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 50 "parse.y" char *string; char symbol; struct string_list *sl; enum av_rule_flavor av_flavor; enum node_flavor node_flavor; #line 335 "parse.c" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif /* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE YYLTYPE; struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; }; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif int yyparse (yyscan_t scanner); /* "%code provides" blocks. */ #line 75 "parse.y" // number of lines stored, printed on parse errors for multiline statements #define LINES_TO_CACHE 5 // global prototype struct policy_node *yyparse_wrapper(FILE *filefd, const char *filename, enum node_flavor expected_flavor); #line 369 "parse.c" #endif /* !YY_YY_PARSE_H_INCLUDED */ /* Second part of user prologue. */ #line 58 "parse.y" // local variables and functions static const char *parsing_filename; static struct policy_node *cur; static enum node_flavor expected_node_flavor; static void yyerror(const YYLTYPE *locp, yyscan_t yyscanner, char const *msg); // lexer extern void yyrestart(FILE *input_file , yyscan_t yyscanner); extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner); extern int yylex_init(yyscan_t* scanner); extern int yylex_destroy(yyscan_t scanner); extern char *current_lines[LINES_TO_CACHE]; extern unsigned line_cache_index; extern void reset_current_lines(void); #line 391 "parse.c" #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int16 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ + YYSIZEOF (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 29 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 1330 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 89 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 115 /* YYNRULES -- Number of rules. */ #define YYNRULES 279 /* YYNSTATES -- Number of states. */ #define YYNSTATES 587 #define YYUNDEFTOK 2 #define YYMAXUTOK 343 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { 0, 194, 194, 197, 199, 201, 203, 205, 207, 209, 211, 213, 219, 223, 225, 229, 233, 235, 240, 248, 258, 260, 264, 266, 270, 274, 276, 280, 284, 286, 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 345, 353, 355, 357, 359, 361, 363, 367, 369, 371, 373, 380, 382, 384, 386, 390, 394, 398, 401, 405, 407, 409, 411, 415, 419, 421, 423, 425, 429, 431, 433, 437, 439, 441, 445, 447, 449, 453, 455, 457, 459, 463, 465, 469, 471, 477, 481, 483, 489, 500, 504, 507, 510, 512, 516, 520, 522, 526, 529, 534, 537, 541, 542, 540, 547, 551, 554, 557, 557, 562, 566, 568, 572, 576, 581, 586, 591, 596, 601, 603, 603, 606, 606, 609, 613, 617, 619, 621, 623, 627, 627, 632, 634, 638, 638, 642, 646, 650, 652, 654, 658, 660, 662, 664, 666, 668, 670, 672, 674, 676, 680, 682, 684, 686, 688, 690, 692, 694, 698, 698, 700, 700, 704, 706, 708, 710, 714, 716, 718, 720, 724, 726, 728, 735, 740, 744, 746, 753, 755, 762, 764, 768, 770, 775, 779, 779, 782, 782, 787, 789, 793, 795, 799, 803, 807, 809, 813, 817, 821, 825, 827, 831, 833, 835, 839, 839, 844, 846, 850, 852, 856, 858, 860, 864, 866, 870, 872, 876, 878, 880, 882, 884, 888, 890, 894, 898, 903, 905, 912, 914, 918, 920, 924, 926, 930, 940, 944, 946, 951, 953, 957, 959, 963, 965, 969, 982, 994, 996, 1000, 1002, 1006, 1008, 1012, 1014, 1018, 1026, 1034, 1044, 1048, 1052, 1054, 1058, 1060 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 1 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "STRING", "NUM_STRING", "IPV4", "IPV6", "NUMBER", "QUOTED_STRING", "VERSION_NO", "SELINT_COMMAND", "UNKNOWN_TOKEN", "POLICY_MODULE", "MODULE", "TYPE", "TYPEALIAS", "ALIAS", "ATTRIBUTE", "BOOL", "TYPE_ATTRIBUTE", "ROLE_ATTRIBUTE", "ROLE", "TYPES", "ATTRIBUTE_ROLE", "ALLOW", "ALLOW_XPERM", "AUDIT_ALLOW", "AUDIT_ALLOW_XPERM", "DONT_AUDIT", "DONT_AUDIT_XPERM", "NEVER_ALLOW", "NEVER_ALLOW_XPERM", "TYPE_TRANSITION", "TYPE_MEMBER", "TYPE_CHANGE", "RANGE_TRANSITION", "ROLE_TRANSITION", "OPTIONAL_POLICY", "GEN_REQUIRE", "GEN_BOOL", "GEN_TUNABLE", "REQUIRE", "TUNABLE_POLICY", "IFELSE", "REFPOLICYWARN", "CLASS", "COMMON", "INHERITS", "IFDEF", "IFNDEF", "IF", "ELSE", "GENFSCON", "SID", "PORTCON", "NETIFCON", "NODECON", "FS_USE_TRANS", "FS_USE_XATTR", "FS_USE_TASK", "DEFINE", "GEN_USER", "GEN_CONTEXT", "PERMISSIVE", "TYPEBOUNDS", "INTERFACE", "TEMPLATE", "USERDEBUG_OR_ENG", "FILE_TYPE_SPECIFIER", "OPEN_PAREN", "COMMA", "PERIOD", "CLOSE_PAREN", "OPEN_CURLY", "CLOSE_CURLY", "COLON", "SEMICOLON", "BACKTICK", "SINGLE_QUOTE", "TILDA", "STAR", "DASH", "AND", "OR", "XOR", "NOT", "EQUAL", "NOT_EQUAL", "COMMENT", "$accept", "selinux_file", "te_policy", "comments", "comment", "maybe_selint_disable", "header", "header_version", "maybe_header_version", "body", "lines", "line", "bare_line", "declaration", "type_declaration", "bool_declaration", "type_alias", "type_attribute", "role_attribute", "rule", "av_type", "xperm_rule", "xperm_av_type", "xperm_list", "xperm_items", "xperm_item", "string_list", "strings", "sl_item", "comma_string_list", "role_allow", "role_types", "type_transition", "range_transition", "role_transition", "interface_call", "optional_block", "$@1", "$@2", "optional_open", "require", "$@3", "gen_require_begin", "require_lines", "require_line", "require_bare", "$@4", "$@5", "m4_simple_macro", "m4_call", "ifdef", "$@6", "if_or_ifn", "ifelse", "$@7", "refpolicywarn", "userdebug_or_eng", "arbitrary_m4_string", "m4_string_elem", "condition", "m4_args", "$@8", "$@9", "m4_argument", "arg", "args", "mls_range", "mls_level", "mls_component", "cond_expr", "boolean_block", "boolean_open", "tunable_block", "$@10", "$@11", "genfscon", "genfscon_context", "sid", "portcon", "port_range", "netifcon", "nodecon", "two_ip_addrs", "fs_use", "define", "$@12", "define_name", "define_content", "define_expansion", "maybe_string_comma", "gen_user", "context", "raw_context", "permissive", "typebounds", "if_file", "if_lines", "if_line", "interface_def", "start_interface", "end_interface", "if_keyword", "spt_file", "spt_lines", "spt_line", "support_def", "av_file", "av_contents", "av_content", "av_definition", "av_class_definition", "av_common_definition", "av_permission_list", "av_permissions", "av_permission", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_int16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343 }; # endif #define YYPACT_NINF (-446) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-25) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { 161, 6, 82, 148, 166, 108, -446, -446, -446, 190, -446, 229, 122, 1186, -446, -18, 192, 146, -446, -21, -446, -2, -446, -446, 230, 251, -1, 174, 173, -446, -446, -446, -446, -446, -446, -446, 188, 276, 280, 284, 295, 300, 303, 315, 323, -446, -446, -446, -446, -446, -446, -446, -446, 73, 73, 73, 73, 73, 265, 281, 285, 287, 264, 291, 296, 301, 342, -446, -446, 305, 268, 346, 370, 375, 304, 378, 381, 383, 319, 320, 384, 387, 322, -446, -446, -446, 466, -446, 192, -446, -446, -446, -446, -446, -446, -446, 73, -446, 73, -446, -446, -446, -446, -446, -446, -446, 538, -446, 263, -446, -446, -446, 324, -446, -446, -446, -446, -446, 32, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -18, -446, -446, -446, 610, 317, -446, -21, -446, -446, -446, -2, -446, -446, 325, -446, -446, 321, 397, 33, -446, -446, 398, 189, 4, 389, 333, 337, 405, 405, 19, 344, -446, -446, 34, 73, -446, 418, 73, -446, 73, 73, 73, 73, 348, 192, 426, 14, 192, 353, -446, 356, 73, 192, 428, 432, 106, 83, 106, 431, 434, 106, 106, 106, 106, -446, 168, 365, 435, 366, -446, -446, 73, 73, 372, 682, 405, 405, 405, 405, 405, 442, 192, -446, 310, -446, 192, 377, 371, -446, 32, 32, 332, -446, 379, 610, -446, 444, -446, -446, 251, 380, -446, 174, -446, -446, 30, -446, 376, -446, -446, -446, -446, -446, 62, 15, 209, -446, -446, -446, 147, 73, 405, -446, 73, -446, -446, -446, -13, -12, 73, -446, -446, 42, -446, -446, -446, 374, 382, 385, 386, 31, 192, -446, 392, 393, 452, -446, -446, 32, -446, 110, 394, -446, 175, 175, 396, 390, -446, -446, -446, 395, 106, 106, -446, -446, -446, 399, 401, 402, 20, 404, -446, 168, -446, 403, 1186, 254, 407, -446, 150, -8, 1, 13, 118, 119, 73, 1242, -446, -446, -446, 391, 453, 340, 266, 439, 32, 32, 32, 32, 32, -446, -446, 450, -446, -446, -446, -446, -446, 443, 75, 436, 460, -446, 454, 455, 459, -446, 228, -446, -446, 153, 154, 461, 532, -446, -446, 462, -446, -446, 73, 73, 73, 73, 464, 73, -446, 540, 541, 467, 1242, 32, 169, 193, 37, -446, -446, -446, -446, -446, -446, -446, -446, -446, 89, -446, 468, 110, -446, 106, -446, -446, -446, 544, 545, 542, -446, -446, -446, -446, -446, -446, 547, 481, -446, 34, -446, 754, 73, -446, 73, -446, -446, -446, -446, -446, -446, -446, 484, 354, 581, 507, -446, 1186, 213, 114, 266, 502, -446, 530, 526, -446, -446, 62, 601, -446, 603, 603, -446, 405, -446, -446, -446, -446, -446, 604, 605, 606, 603, -446, 607, 543, 546, 549, 318, 260, -446, -446, -446, -446, 826, -446, 534, 548, -446, -446, 557, 197, -446, 539, 70, 550, 164, 551, 73, 618, 579, -446, 585, 583, 602, 898, 598, 73, -446, -446, -446, -446, 170, 99, 600, 608, 611, 613, -446, -446, 675, -446, 609, 206, 37, -446, 970, -446, -446, 677, 603, -446, -446, -446, 110, -446, -446, 603, -446, 614, 209, -446, -446, 612, -446, 630, -446, 16, -446, 615, -446, -446, -446, -446, -446, 620, -446, -446, -446, -446, 619, 220, 617, 623, -446, 628, 1186, 651, -446, 656, 661, 666, -446, -446, 221, 603, 58, -446, -446, 603, -446, 1042, -446, 1242, 232, 1186, -446, 676, -446, -446, -446, 678, 253, 679, 1242, 362, -446, 1114, -446, -446, 603, -446, -446, 1234, -446, -446, 680, 681, -446, -446 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int16 yydefact[] = { 2, 0, 0, 0, 0, 0, 253, 254, 15, 0, 3, 11, 13, 0, 5, 244, 17, 0, 7, 256, 9, 264, 269, 270, 0, 0, 0, 0, 0, 1, 4, 6, 8, 10, 14, 57, 141, 0, 0, 0, 0, 0, 0, 0, 0, 76, 81, 77, 82, 78, 83, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, 12, 0, 26, 17, 28, 58, 63, 31, 29, 30, 32, 0, 33, 0, 34, 35, 36, 37, 38, 39, 40, 0, 41, 0, 43, 42, 142, 0, 143, 144, 145, 44, 197, 0, 196, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 248, 243, 246, 247, 16, 0, 0, 260, 255, 258, 259, 268, 263, 266, 267, 23, 21, 20, 0, 0, 0, 271, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 102, 0, 0, 97, 0, 0, 96, 0, 0, 0, 0, 0, 17, 0, 0, 17, 203, 150, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 0, 0, 0, 0, 25, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 140, 0, 128, 17, 0, 0, 167, 0, 0, 0, 245, 0, 0, 250, 0, 257, 265, 0, 0, 19, 272, 278, 279, 0, 277, 0, 91, 92, 93, 184, 115, 0, 0, 0, 183, 87, 187, 0, 0, 0, 64, 0, 59, 68, 104, 0, 0, 0, 61, 62, 0, 99, 95, 101, 0, 0, 0, 0, 0, 17, 126, 0, 0, 0, 124, 201, 0, 175, 0, 0, 200, 0, 0, 0, 0, 209, 234, 211, 212, 0, 0, 216, 217, 215, 0, 0, 0, 0, 0, 231, 0, 241, 0, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 123, 127, 129, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 252, 249, 0, 22, 18, 273, 275, 276, 0, 0, 89, 194, 186, 0, 191, 192, 86, 0, 114, 189, 0, 0, 0, 0, 73, 74, 0, 94, 98, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, 0, 179, 157, 158, 162, 163, 159, 160, 161, 164, 165, 0, 166, 0, 154, 60, 0, 205, 207, 206, 0, 0, 0, 210, 214, 218, 219, 220, 224, 0, 225, 230, 0, 242, 0, 0, 105, 0, 118, 116, 130, 131, 134, 132, 133, 0, 0, 0, 0, 174, 0, 169, 170, 171, 172, 173, 0, 0, 85, 88, 0, 0, 185, 0, 0, 188, 0, 66, 65, 72, 103, 106, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 175, 177, 151, 182, 0, 176, 0, 0, 155, 208, 0, 0, 213, 0, 227, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 90, 195, 190, 193, 0, 0, 0, 0, 0, 0, 69, 71, 0, 125, 0, 0, 179, 180, 0, 156, 152, 0, 0, 235, 223, 229, 0, 226, 222, 0, 153, 0, 0, 119, 122, 0, 146, 198, 251, 0, 67, 0, 107, 109, 110, 111, 113, 0, 175, 204, 178, 181, 239, 0, 0, 0, 75, 0, 0, 138, 175, 0, 0, 0, 108, 70, 0, 0, 0, 236, 228, 0, 80, 0, 136, 0, 0, 0, 261, 0, 202, 240, 238, 0, 0, 0, 0, 0, 147, 0, 262, 237, 0, 232, 120, 0, 139, 199, 0, 0, 233, 137 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -446, -446, 736, 742, -446, -74, -446, 525, -446, -446, -104, -86, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -244, -446, -230, -47, 355, -152, -155, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -312, -211, -446, -446, -446, -446, -446, -446, -446, -107, -446, -446, 235, -446, -367, 415, -196, -445, -446, -446, 261, 414, -446, -411, 327, 328, -446, -446, -446, -446, -446, -446, -446, 479, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, 463, -446, -165, 406, -446, -446, 765, -446, 674, 17, -446, 590, -446, 808, -446, 684, 0, 809, -446, 683, -5, -446, -446, -16, -446, 586 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 9, 10, 11, 12, 135, 13, 148, 232, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 248, 341, 249, 169, 264, 170, 259, 99, 100, 101, 102, 103, 104, 105, 477, 543, 106, 107, 371, 108, 215, 216, 217, 571, 560, 109, 110, 111, 545, 112, 113, 281, 114, 115, 387, 388, 223, 374, 375, 501, 462, 250, 251, 345, 346, 347, 116, 117, 118, 119, 372, 280, 120, 391, 121, 122, 293, 123, 124, 192, 125, 126, 301, 404, 472, 512, 304, 127, 392, 290, 128, 129, 14, 131, 132, 15, 16, 227, 17, 18, 138, 139, 19, 20, 142, 143, 21, 22, 23, 151, 237, 238 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 201, 218, 206, 348, 320, 260, 420, 171, 172, 173, 174, 152, 500, 265, 202, 342, 144, 276, 343, 140, 252, 465, 289, 402, 294, 324, 325, 297, 298, 299, 300, 226, 133, 235, 365, 220, 235, 163, 493, 5, 460, 261, 164, 3, 4, 163, 149, 6, 7, 203, 164, 204, 312, 313, 314, 315, 316, 355, 355, 455, 65, 343, 355, 356, 357, 240, 241, 137, 414, 242, 130, 355, 150, 510, 253, 24, 163, 415, 240, 241, 254, 164, 242, 355, 373, 25, 141, 291, 551, 416, 292, 277, 376, 344, 547, 262, 538, 403, 353, 351, 561, 221, 274, 540, 338, 278, 366, 526, 218, 287, 284, 433, 360, 376, 461, 168, 359, 222, 236, 266, 201, 236, 268, 168, 269, 270, 271, 272, 397, 398, 567, 425, 426, 427, 428, 429, 283, 144, 140, 318, 201, 566, 568, 321, 539, 569, 165, 511, 133, 432, 163, 26, 166, 167, 168, 164, 308, 309, 377, 378, 379, 380, 381, 382, 383, 384, 583, 163, 288, 27, 386, 302, 164, 1, 2, 527, 456, 28, 287, 377, 378, 379, 380, 381, 382, 383, 384, 385, 355, 355, 29, 386, 240, 241, 417, 418, 242, 243, 329, 367, 330, 331, 134, 408, 485, 352, 3, 4, 354, 320, 8, 218, 240, 241, 358, 136, 242, 349, 337, 350, 412, 5, 413, 440, 355, 466, 6, 7, 168, 441, 442, 240, 241, 145, 514, 242, 243, 288, 303, 457, 355, 1, 2, 390, 320, 168, 525, 150, 572, 8, 153, 327, 328, 329, 265, 330, 331, 154, 146, 580, 147, 244, 245, 458, 218, 459, 246, 507, 247, 508, 419, 185, 186, 542, 3, 4, 458, 207, 534, 155, 208, 209, 245, 156, 210, 489, 211, 157, 247, 5, 553, 458, 554, 565, 6, 7, 328, 329, 158, 330, 331, 245, 458, 159, 573, 246, 160, 247, 212, 190, 191, 67, 68, 218, 446, 447, 448, 449, 161, 451, 482, 360, 201, 577, 207, 578, 162, 208, 209, 409, 410, 210, 207, 211, 175, 208, 209, 179, 499, 210, 213, 211, 327, 328, 329, 183, 330, 331, 218, 187, 176, 214, 330, 331, 177, 212, 178, 503, 67, 68, 180, 320, 475, 212, 476, 181, 67, 68, 207, 320, 182, 208, 209, 188, 184, 210, 207, 211, 189, 208, 209, 193, 319, 210, 194, 211, 195, 198, 196, 197, 199, 200, 498, 219, 228, 231, 201, 233, 214, 212, 234, 239, 67, 68, 326, 255, 214, 212, 258, 256, 67, 68, 423, 257, 327, 328, 329, 201, 330, 331, 263, 267, 327, 328, 329, 273, 330, 331, 516, 275, 279, 285, 479, 282, 581, 286, 295, 524, 306, 558, 296, 305, 214, 307, 310, 317, 322, 334, 323, 361, 214, 332, 336, 218, 340, 370, 422, 362, 574, 395, 363, 364, 368, 369, 218, 218, -24, 35, 421, 36, 389, 394, 201, 218, 405, 399, 396, 400, 401, 407, 37, 38, 411, 39, 40, 41, 42, 43, 201, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 424, 431, 67, 68, 69, 434, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 430, 80, 81, 435, 436, 82, 438, 444, 437, 443, 445, 35, 450, 36, 83, 452, 453, 454, 464, 467, 287, 469, 470, 471, 37, 38, 84, 39, 40, 41, 42, 43, 478, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 480, 481, 67, 68, 69, 331, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 483, 80, 81, 484, 486, 82, 343, 490, 491, 492, 494, 35, 504, 36, 83, 495, 205, 509, 496, 497, 505, 517, 513, 515, 37, 38, 84, 39, 40, 41, 42, 43, 506, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 518, 519, 67, 68, 69, 520, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 521, 80, 81, 523, 528, 82, 532, 533, 537, 546, 544, 35, 529, 36, 83, 530, 225, 531, 541, 549, 550, 556, 552, 555, 37, 38, 84, 39, 40, 41, 42, 43, 557, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 559, 562, 67, 68, 69, 563, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 564, 80, 81, 30, 575, 82, 576, 579, 585, 586, 34, 35, 335, 36, 83, 548, 311, 473, 535, 439, 487, 393, 488, 406, 37, 38, 84, 39, 40, 41, 42, 43, 31, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 463, 468, 67, 68, 69, 224, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 333, 80, 81, 32, 33, 82, 229, 339, 0, 230, 0, 35, 0, 36, 83, 0, 474, 0, 0, 0, 0, 0, 0, 0, 37, 38, 84, 39, 40, 41, 42, 43, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 0, 0, 67, 68, 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 80, 81, 0, 0, 82, 0, 0, 0, 0, 0, 35, 0, 36, 83, 0, 502, 0, 0, 0, 0, 0, 0, 0, 37, 38, 84, 39, 40, 41, 42, 43, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 0, 0, 67, 68, 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 80, 81, 0, 0, 82, 0, 0, 0, 0, 0, 35, 522, 36, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 84, 39, 40, 41, 42, 43, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 0, 0, 67, 68, 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 80, 81, 0, 0, 82, 0, 0, 0, 0, 0, 35, 0, 36, 83, 0, 536, 0, 0, 0, 0, 0, 0, 0, 37, 38, 84, 39, 40, 41, 42, 43, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 0, 0, 67, 68, 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 80, 81, 0, 0, 82, 0, 0, 0, 0, 0, 35, 0, 36, 83, 0, 570, 0, 0, 0, 0, 0, 0, 0, 37, 38, 84, 39, 40, 41, 42, 43, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 0, 0, 67, 68, 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 80, 81, 0, 0, 82, 0, 0, 0, 0, 0, 35, 582, 36, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 84, 39, 40, 41, 42, 43, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 0, 0, 67, 68, 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 207, 80, 81, 208, 209, 82, 0, 210, 207, 211, 0, 208, 209, 0, 83, 210, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 212, 0, 0, 67, 68, 0, 0, 0, 212, 0, 0, 67, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, 214 }; static const yytype_int16 yycheck[] = { 86, 108, 106, 247, 215, 160, 318, 54, 55, 56, 57, 27, 457, 165, 88, 245, 21, 3, 3, 19, 16, 388, 187, 3, 189, 221, 222, 192, 193, 194, 195, 135, 15, 3, 3, 3, 3, 3, 449, 60, 3, 22, 8, 45, 46, 3, 47, 65, 66, 96, 8, 98, 207, 208, 209, 210, 211, 70, 70, 371, 44, 3, 70, 76, 76, 3, 4, 88, 76, 7, 88, 70, 73, 3, 70, 69, 3, 76, 3, 4, 76, 8, 7, 70, 280, 3, 88, 4, 533, 76, 7, 77, 3, 78, 78, 76, 507, 77, 253, 251, 545, 69, 176, 514, 74, 179, 75, 8, 215, 3, 184, 341, 264, 3, 77, 81, 74, 85, 88, 166, 206, 88, 169, 81, 171, 172, 173, 174, 293, 294, 72, 327, 328, 329, 330, 331, 183, 142, 138, 213, 226, 552, 553, 217, 511, 556, 73, 77, 131, 74, 3, 3, 79, 80, 81, 8, 203, 204, 69, 70, 71, 72, 73, 74, 75, 76, 577, 3, 62, 3, 81, 3, 8, 12, 13, 76, 372, 69, 3, 69, 70, 71, 72, 73, 74, 75, 76, 77, 70, 70, 0, 81, 3, 4, 76, 76, 7, 8, 84, 273, 86, 87, 10, 307, 434, 252, 45, 46, 255, 420, 88, 318, 3, 4, 261, 69, 7, 70, 234, 72, 70, 60, 72, 70, 70, 390, 65, 66, 81, 76, 76, 3, 4, 3, 70, 7, 8, 62, 70, 70, 70, 12, 13, 68, 455, 81, 76, 73, 560, 88, 77, 82, 83, 84, 406, 86, 87, 69, 7, 571, 9, 72, 73, 70, 371, 72, 77, 70, 79, 72, 317, 3, 4, 517, 45, 46, 70, 14, 72, 3, 17, 18, 73, 3, 21, 440, 23, 3, 79, 60, 70, 70, 72, 72, 65, 66, 83, 84, 3, 86, 87, 73, 70, 3, 72, 77, 3, 79, 45, 5, 6, 48, 49, 420, 361, 362, 363, 364, 3, 366, 424, 473, 408, 70, 14, 72, 3, 17, 18, 75, 76, 21, 14, 23, 69, 17, 18, 73, 78, 21, 77, 23, 82, 83, 84, 3, 86, 87, 455, 3, 69, 88, 86, 87, 69, 45, 69, 461, 48, 49, 69, 572, 409, 45, 411, 69, 48, 49, 14, 580, 69, 17, 18, 3, 69, 21, 14, 23, 3, 17, 18, 3, 72, 21, 3, 23, 3, 3, 69, 69, 3, 69, 74, 69, 77, 70, 482, 76, 88, 45, 3, 3, 48, 49, 72, 16, 88, 45, 3, 76, 48, 49, 72, 76, 82, 83, 84, 503, 86, 87, 76, 3, 82, 83, 84, 77, 86, 87, 475, 3, 77, 3, 78, 77, 72, 3, 5, 484, 3, 543, 6, 76, 88, 77, 72, 3, 69, 3, 77, 75, 88, 72, 72, 560, 78, 3, 3, 75, 562, 69, 75, 75, 70, 70, 571, 572, 0, 1, 77, 3, 76, 75, 558, 580, 70, 76, 81, 76, 76, 76, 14, 15, 75, 17, 18, 19, 20, 21, 574, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 73, 70, 48, 49, 50, 81, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 78, 63, 64, 71, 78, 67, 75, 3, 81, 76, 76, 1, 76, 3, 76, 3, 3, 78, 78, 3, 3, 7, 3, 70, 14, 15, 88, 17, 18, 19, 20, 21, 76, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 3, 78, 48, 49, 50, 87, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 70, 63, 64, 77, 3, 67, 3, 3, 3, 3, 3, 1, 78, 3, 76, 72, 78, 78, 72, 70, 72, 3, 72, 72, 14, 15, 88, 17, 18, 19, 20, 21, 75, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 77, 72, 48, 49, 50, 78, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 70, 63, 64, 77, 76, 67, 3, 70, 3, 51, 70, 1, 76, 3, 76, 76, 78, 76, 76, 76, 72, 70, 75, 78, 14, 15, 88, 17, 18, 19, 20, 21, 76, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 77, 73, 48, 49, 50, 72, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 78, 63, 64, 11, 72, 67, 72, 72, 72, 72, 12, 1, 231, 3, 76, 524, 78, 406, 501, 349, 437, 286, 438, 304, 14, 15, 88, 17, 18, 19, 20, 21, 11, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 385, 395, 48, 49, 50, 131, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 226, 63, 64, 11, 11, 67, 138, 237, -1, 142, -1, 1, -1, 3, 76, -1, 78, -1, -1, -1, -1, -1, -1, -1, 14, 15, 88, 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, 63, 64, -1, -1, 67, -1, -1, -1, -1, -1, 1, -1, 3, 76, -1, 78, -1, -1, -1, -1, -1, -1, -1, 14, 15, 88, 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, 63, 64, -1, -1, 67, -1, -1, -1, -1, -1, 1, 74, 3, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, 15, 88, 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, 63, 64, -1, -1, 67, -1, -1, -1, -1, -1, 1, -1, 3, 76, -1, 78, -1, -1, -1, -1, -1, -1, -1, 14, 15, 88, 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, 63, 64, -1, -1, 67, -1, -1, -1, -1, -1, 1, -1, 3, 76, -1, 78, -1, -1, -1, -1, -1, -1, -1, 14, 15, 88, 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, 63, 64, -1, -1, 67, -1, -1, -1, -1, -1, 1, 74, 3, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, 15, 88, 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 14, 63, 64, 17, 18, 67, -1, 21, 14, 23, -1, 17, 18, -1, 76, 21, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, -1, 45, -1, -1, 48, 49, -1, -1, -1, 45, -1, -1, 48, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 78, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, -1, -1, -1, -1, 88 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 12, 13, 45, 46, 60, 65, 66, 88, 90, 91, 92, 93, 95, 184, 187, 188, 190, 191, 194, 195, 198, 199, 200, 69, 3, 3, 3, 69, 0, 91, 184, 191, 195, 92, 1, 3, 14, 15, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 48, 49, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 64, 67, 76, 88, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 119, 120, 121, 122, 123, 124, 125, 128, 129, 131, 137, 138, 139, 141, 142, 144, 145, 158, 159, 160, 161, 164, 166, 167, 169, 170, 172, 173, 179, 182, 183, 88, 185, 186, 187, 10, 94, 69, 88, 192, 193, 194, 88, 196, 197, 198, 3, 7, 9, 96, 47, 73, 201, 201, 77, 69, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 73, 79, 80, 81, 115, 117, 115, 115, 115, 115, 69, 69, 69, 69, 73, 69, 69, 69, 3, 69, 3, 4, 3, 3, 3, 5, 6, 171, 3, 3, 3, 69, 69, 3, 3, 69, 100, 94, 115, 115, 78, 99, 14, 17, 18, 21, 23, 45, 77, 88, 132, 133, 134, 141, 69, 3, 69, 85, 148, 186, 78, 99, 189, 77, 193, 197, 70, 97, 76, 3, 3, 88, 202, 203, 3, 3, 4, 7, 8, 72, 73, 77, 79, 112, 114, 153, 154, 16, 70, 76, 16, 76, 76, 3, 118, 118, 22, 76, 76, 116, 117, 115, 3, 115, 115, 115, 115, 115, 77, 94, 3, 3, 77, 94, 77, 163, 143, 77, 115, 94, 3, 3, 3, 62, 180, 181, 4, 7, 168, 180, 5, 6, 180, 180, 180, 180, 174, 3, 70, 178, 76, 3, 77, 115, 115, 72, 78, 118, 118, 118, 118, 118, 3, 94, 72, 133, 94, 69, 77, 148, 148, 72, 82, 83, 84, 86, 87, 72, 189, 3, 96, 72, 201, 74, 203, 78, 113, 114, 3, 78, 155, 156, 157, 112, 70, 72, 117, 115, 118, 115, 70, 76, 76, 115, 74, 117, 75, 75, 75, 75, 3, 75, 94, 70, 70, 3, 130, 162, 148, 149, 150, 3, 69, 70, 71, 72, 73, 74, 75, 76, 77, 81, 146, 147, 76, 68, 165, 180, 165, 75, 69, 81, 180, 180, 76, 76, 76, 3, 77, 175, 70, 178, 76, 99, 75, 76, 75, 70, 72, 76, 76, 76, 76, 76, 115, 132, 77, 3, 72, 73, 148, 148, 148, 148, 148, 78, 70, 74, 114, 81, 71, 78, 81, 75, 153, 70, 76, 76, 76, 3, 76, 115, 115, 115, 115, 76, 115, 3, 3, 78, 132, 148, 70, 70, 72, 3, 77, 152, 147, 78, 146, 180, 3, 181, 7, 3, 70, 176, 116, 78, 115, 115, 126, 76, 78, 3, 78, 99, 70, 77, 114, 3, 156, 157, 118, 3, 3, 3, 155, 3, 72, 72, 70, 74, 78, 149, 151, 78, 99, 78, 72, 75, 70, 72, 78, 3, 77, 177, 72, 70, 72, 115, 3, 77, 72, 78, 70, 74, 77, 115, 76, 8, 76, 76, 76, 76, 76, 3, 70, 72, 152, 78, 3, 155, 146, 155, 76, 112, 127, 70, 140, 51, 78, 144, 76, 72, 149, 75, 70, 72, 78, 70, 76, 99, 77, 136, 149, 73, 72, 78, 72, 155, 72, 155, 155, 78, 135, 132, 72, 99, 72, 72, 70, 72, 72, 132, 72, 74, 155, 78, 72, 72 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92, 92, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 99, 99, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 104, 105, 106, 107, 108, 109, 109, 109, 109, 110, 111, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116, 117, 117, 117, 118, 118, 119, 120, 121, 121, 121, 121, 122, 123, 123, 124, 124, 125, 125, 126, 127, 125, 128, 129, 129, 130, 129, 131, 132, 132, 133, 134, 134, 134, 134, 134, 134, 135, 134, 136, 134, 134, 137, 138, 138, 138, 138, 140, 139, 141, 141, 143, 142, 144, 145, 146, 146, 146, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, 148, 148, 148, 150, 149, 151, 149, 152, 152, 152, 152, 153, 153, 153, 153, 154, 154, 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, 159, 160, 162, 161, 163, 161, 164, 164, 165, 165, 166, 167, 168, 168, 168, 169, 170, 171, 171, 172, 172, 172, 174, 173, 175, 175, 176, 176, 177, 177, 177, 178, 178, 179, 179, 180, 180, 180, 180, 180, 181, 181, 182, 183, 184, 184, 185, 185, 186, 186, 187, 187, 188, 189, 190, 190, 191, 191, 192, 192, 193, 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199, 199, 199, 200, 201, 202, 202, 203, 203 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { 0, 2, 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 0, 5, 4, 1, 1, 2, 0, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 3, 3, 1, 3, 5, 5, 7, 3, 6, 8, 6, 5, 4, 4, 7, 1, 1, 1, 1, 8, 1, 1, 1, 1, 3, 2, 1, 2, 1, 3, 1, 1, 1, 3, 2, 1, 1, 2, 1, 1, 2, 1, 3, 1, 4, 5, 7, 8, 7, 7, 7, 5, 7, 4, 3, 4, 3, 0, 0, 10, 4, 6, 3, 0, 6, 3, 2, 1, 2, 3, 3, 3, 3, 3, 4, 0, 11, 0, 9, 1, 1, 1, 1, 1, 1, 0, 9, 1, 1, 0, 5, 6, 6, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 0, 2, 0, 4, 0, 2, 3, 1, 1, 1, 3, 2, 1, 3, 2, 3, 1, 1, 3, 1, 3, 1, 1, 6, 10, 3, 0, 9, 0, 7, 4, 4, 1, 2, 3, 4, 1, 1, 3, 4, 3, 2, 2, 4, 4, 4, 0, 6, 3, 1, 0, 2, 0, 3, 1, 2, 1, 10, 12, 1, 4, 6, 8, 7, 5, 7, 3, 4, 2, 1, 2, 1, 1, 1, 4, 3, 7, 2, 1, 1, 2, 1, 2, 1, 1, 1, 10, 11, 2, 1, 2, 1, 1, 1, 1, 1, 3, 4, 5, 3, 3, 2, 1, 1, 1 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (&yylloc, scanner, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (N) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (0) #endif #define YYRHSLOC(Rhs, K) ((Rhs)[K]) /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ YY_ATTRIBUTE_UNUSED static int yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) { int res = 0; int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; if (0 <= yylocp->first_line) { res += YYFPRINTF (yyo, "%d", yylocp->first_line); if (0 <= yylocp->first_column) res += YYFPRINTF (yyo, ".%d", yylocp->first_column); } if (0 <= yylocp->last_line) { if (yylocp->first_line < yylocp->last_line) { res += YYFPRINTF (yyo, "-%d", yylocp->last_line); if (0 <= end_col) res += YYFPRINTF (yyo, ".%d", end_col); } else if (0 <= end_col && yylocp->first_column < end_col) res += YYFPRINTF (yyo, "-%d", end_col); } return res; } # define YY_LOCATION_PRINT(File, Loc) \ yy_location_print_ (File, &(Loc)) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, Location, scanner); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, yyscan_t scanner) { FILE *yyoutput = yyo; YYUSE (yyoutput); YYUSE (yylocationp); YYUSE (scanner); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, yyscan_t scanner) { YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); YY_LOCATION_PRINT (yyo, *yylocationp); YYFPRINTF (yyo, ": "); yy_symbol_value_print (yyo, yytype, yyvaluep, yylocationp, scanner); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, yyscan_t scanner) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[+yyssp[yyi + 1 - yynrhs]], &yyvsp[(yyi + 1) - (yynrhs)] , &(yylsp[(yyi + 1) - (yynrhs)]) , scanner); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, yylsp, Rule, scanner); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, yy_state_t *yyssp, int yytoken) { enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Actual size of YYARG. */ int yycount = 0; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[+*yyssp]; YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); yysize = yysize0; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return 2; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { /* Don't count the "%s"s in the final size, but reserve room for the terminator. */ YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return 2; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, yyscan_t scanner) { YYUSE (yyvaluep); YYUSE (yylocationp); YYUSE (scanner); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN switch (yytype) { case 3: /* STRING */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1953 "parse.c" break; case 4: /* NUM_STRING */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1959 "parse.c" break; case 5: /* IPV4 */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1965 "parse.c" break; case 6: /* IPV6 */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1971 "parse.c" break; case 7: /* NUMBER */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1977 "parse.c" break; case 8: /* QUOTED_STRING */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1983 "parse.c" break; case 9: /* VERSION_NO */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1989 "parse.c" break; case 10: /* SELINT_COMMAND */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 1995 "parse.c" break; case 94: /* maybe_selint_disable */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 2001 "parse.c" break; case 112: /* xperm_list */ #line 190 "parse.y" { free_string_list(((*yyvaluep).sl)); } #line 2007 "parse.c" break; case 113: /* xperm_items */ #line 190 "parse.y" { free_string_list(((*yyvaluep).sl)); } #line 2013 "parse.c" break; case 114: /* xperm_item */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 2019 "parse.c" break; case 115: /* string_list */ #line 190 "parse.y" { free_string_list(((*yyvaluep).sl)); } #line 2025 "parse.c" break; case 116: /* strings */ #line 190 "parse.y" { free_string_list(((*yyvaluep).sl)); } #line 2031 "parse.c" break; case 117: /* sl_item */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 2037 "parse.c" break; case 118: /* comma_string_list */ #line 190 "parse.y" { free_string_list(((*yyvaluep).sl)); } #line 2043 "parse.c" break; case 153: /* arg */ #line 190 "parse.y" { free_string_list(((*yyvaluep).sl)); } #line 2049 "parse.c" break; case 154: /* args */ #line 190 "parse.y" { free_string_list(((*yyvaluep).sl)); } #line 2055 "parse.c" break; case 155: /* mls_range */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 2061 "parse.c" break; case 156: /* mls_level */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 2067 "parse.c" break; case 157: /* mls_component */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 2073 "parse.c" break; case 178: /* maybe_string_comma */ #line 189 "parse.y" { free(((*yyvaluep).string)); } #line 2079 "parse.c" break; default: break; } YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (yyscan_t scanner) { /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Location data for the lookahead symbol. */ static YYLTYPE yyloc_default # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL = { 1, 1, 1, 1 } # endif ; YYLTYPE yylloc = yyloc_default; /* Number of syntax errors so far. */ int yynerrs; yy_state_fast_t yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. 'yyls': related to locations. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss; yy_state_t *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; /* The location stack. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls; YYLTYPE *yylsp; /* The locations where the error started and ended. */ YYLTYPE yyerror_range[3]; YYPTRDIFF_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yylsp = yyls = yylsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ yylsp[0] = yylloc; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE goto yyexhaustedlab; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yyls1, yysize * YYSIZEOF (*yylsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; yyls = yyls1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; yylsp = yyls + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (&yylval, &yylloc, scanner); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 195 "parse.y" { cur->flavor = NODE_EMPTY; } #line 2381 "parse.c" break; case 15: #line 229 "parse.y" { insert_comment(&cur, (yyloc).first_line); } #line 2387 "parse.c" break; case 17: #line 235 "parse.y" { (yyval.string) = NULL; } #line 2393 "parse.c" break; case 18: #line 240 "parse.y" { if (expected_node_flavor != NODE_TE_FILE) { free((yyvsp[-2].string)); const struct location loc = { (yylsp[-4]).first_line, (yylsp[-4]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected te-file parsed"); YYERROR; } insert_header(&cur, (yyvsp[-2].string), HEADER_MACRO, (yyloc).first_line); free((yyvsp[-2].string)); } #line 2405 "parse.c" break; case 19: #line 248 "parse.y" { if (expected_node_flavor != NODE_TE_FILE) { free((yyvsp[-2].string)); const struct location loc = { (yylsp[-3]).first_line, (yylsp[-3]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected te-file parsed"); YYERROR; } insert_header(&cur, (yyvsp[-2].string), HEADER_BARE, (yyloc).first_line); free((yyvsp[-2].string)); } #line 2417 "parse.c" break; case 20: #line 258 "parse.y" { free((yyvsp[0].string)); } #line 2423 "parse.c" break; case 21: #line 260 "parse.y" { free((yyvsp[0].string)); } #line 2429 "parse.c" break; case 27: #line 280 "parse.y" { save_command(cur, (yyvsp[0].string)); free((yyvsp[0].string)); } #line 2435 "parse.c" break; case 55: #line 338 "parse.y" { insert_semicolon(&cur, (yyloc).first_line); } #line 2441 "parse.c" break; case 57: #line 345 "parse.y" { const struct location loc = { (yylsp[0]).first_line, (yylsp[0]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Invalid statement"); YYABORT; } #line 2451 "parse.c" break; case 59: #line 355 "parse.y" { insert_declaration(&cur, DECL_ATTRIBUTE, (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2457 "parse.c" break; case 60: #line 357 "parse.y" { insert_declaration(&cur, DECL_CLASS, (yyvsp[-2].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-2].string)); } #line 2463 "parse.c" break; case 61: #line 359 "parse.y" { insert_declaration(&cur, DECL_ROLE, (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2469 "parse.c" break; case 62: #line 361 "parse.y" { insert_declaration(&cur, DECL_ATTRIBUTE_ROLE, (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2475 "parse.c" break; case 64: #line 367 "parse.y" { insert_declaration(&cur, DECL_TYPE, (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2481 "parse.c" break; case 65: #line 369 "parse.y" { insert_declaration(&cur, DECL_TYPE, (yyvsp[-3].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-3].string)); } #line 2487 "parse.c" break; case 66: #line 371 "parse.y" { insert_declaration(&cur, DECL_TYPE, (yyvsp[-3].string), NULL, (yyloc).first_line); free((yyvsp[-3].string)); insert_aliases(&cur, (yyvsp[-1].sl), DECL_TYPE, (yyloc).first_line); } #line 2493 "parse.c" break; case 67: #line 373 "parse.y" { insert_declaration(&cur, DECL_TYPE, (yyvsp[-5].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-5].string)); insert_aliases(&cur, (yyvsp[-3].sl), DECL_TYPE, (yyloc).first_line); } #line 2502 "parse.c" break; case 68: #line 380 "parse.y" { insert_declaration(&cur, DECL_BOOL, (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2508 "parse.c" break; case 69: #line 382 "parse.y" { insert_declaration(&cur, DECL_BOOL, (yyvsp[-3].string), NULL, (yyloc).first_line); free((yyvsp[-3].string)); free((yyvsp[-1].string)); } #line 2514 "parse.c" break; case 70: #line 384 "parse.y" { insert_declaration(&cur, DECL_BOOL, (yyvsp[-4].string), NULL, (yyloc).first_line); free((yyvsp[-4].string)); free((yyvsp[-1].string)); } #line 2520 "parse.c" break; case 71: #line 386 "parse.y" { insert_declaration(&cur, DECL_BOOL, (yyvsp[-3].string), NULL, (yyloc).first_line); free((yyvsp[-3].string)); free((yyvsp[-1].string)); } #line 2526 "parse.c" break; case 72: #line 390 "parse.y" { insert_type_alias(&cur, (yyvsp[-3].string), (yyloc).first_line); insert_aliases(&cur, (yyvsp[-1].sl), DECL_TYPE, (yyloc).first_line); free((yyvsp[-3].string)); } #line 2532 "parse.c" break; case 73: #line 394 "parse.y" { insert_type_attribute(&cur, (yyvsp[-2].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-2].string)); } #line 2538 "parse.c" break; case 74: #line 398 "parse.y" { insert_role_attribute(&cur, (yyvsp[-2].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-2].string)); } #line 2544 "parse.c" break; case 75: #line 401 "parse.y" { insert_av_rule(&cur, (yyvsp[-6].av_flavor), (yyvsp[-5].sl), (yyvsp[-4].sl), (yyvsp[-2].sl), (yyvsp[-1].sl), (yyloc).first_line); } #line 2550 "parse.c" break; case 76: #line 405 "parse.y" { (yyval.av_flavor) = AV_RULE_ALLOW; } #line 2556 "parse.c" break; case 77: #line 407 "parse.y" { (yyval.av_flavor) = AV_RULE_AUDITALLOW; } #line 2562 "parse.c" break; case 78: #line 409 "parse.y" { (yyval.av_flavor) = AV_RULE_DONTAUDIT; } #line 2568 "parse.c" break; case 79: #line 411 "parse.y" { (yyval.av_flavor) = AV_RULE_NEVERALLOW; } #line 2574 "parse.c" break; case 80: #line 415 "parse.y" { insert_xperm_av_rule(&cur, (yyvsp[-7].av_flavor), (yyvsp[-6].sl), (yyvsp[-5].sl), (yyvsp[-3].sl), (yyvsp[-2].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-2].string)); } #line 2580 "parse.c" break; case 81: #line 419 "parse.y" { (yyval.av_flavor) = AV_RULE_ALLOW; } #line 2586 "parse.c" break; case 82: #line 421 "parse.y" { (yyval.av_flavor) = AV_RULE_AUDITALLOW; } #line 2592 "parse.c" break; case 83: #line 423 "parse.y" { (yyval.av_flavor) = AV_RULE_DONTAUDIT; } #line 2598 "parse.c" break; case 84: #line 425 "parse.y" { (yyval.av_flavor) = AV_RULE_NEVERALLOW; } #line 2604 "parse.c" break; case 85: #line 429 "parse.y" { (yyval.sl) = (yyvsp[-1].sl); } #line 2610 "parse.c" break; case 86: #line 431 "parse.y" { (yyval.sl) = sl_from_str("~"); (yyval.sl)->next = (yyvsp[0].sl); } #line 2616 "parse.c" break; case 87: #line 433 "parse.y" { (yyval.sl) = sl_from_str_consume((yyvsp[0].string)); } #line 2622 "parse.c" break; case 88: #line 437 "parse.y" { (yyval.sl) = concat_string_lists((yyvsp[-1].sl), sl_from_str_consume((yyvsp[0].string))); } #line 2628 "parse.c" break; case 89: #line 439 "parse.y" { (yyval.sl) = sl_from_str_consume((yyvsp[0].string)); } #line 2634 "parse.c" break; case 90: #line 441 "parse.y" { (yyval.sl) = concat_string_lists(sl_from_str_consume((yyvsp[-2].string)), concat_string_lists(sl_from_str("-"), sl_from_str_consume((yyvsp[0].string)))); } #line 2640 "parse.c" break; case 94: #line 453 "parse.y" { (yyval.sl) = (yyvsp[-1].sl); } #line 2646 "parse.c" break; case 95: #line 455 "parse.y" { (yyval.sl) = sl_from_str("~"); (yyval.sl)->next = (yyvsp[0].sl); } #line 2652 "parse.c" break; case 96: #line 457 "parse.y" { (yyval.sl) = sl_from_str_consume((yyvsp[0].string)); } #line 2658 "parse.c" break; case 97: #line 459 "parse.y" { (yyval.sl) = sl_from_str("*"); } #line 2664 "parse.c" break; case 98: #line 463 "parse.y" { (yyval.sl) = concat_string_lists((yyvsp[-1].sl), sl_from_str_consume((yyvsp[0].string))); } #line 2670 "parse.c" break; case 99: #line 465 "parse.y" { (yyval.sl) = sl_from_str_consume((yyvsp[0].string)); } #line 2676 "parse.c" break; case 101: #line 471 "parse.y" { (yyval.string) = malloc(sizeof(char) * (strlen((yyvsp[0].string)) + 2)); (yyval.string)[0] = '-'; (yyval.string)[1] = '\0'; strcat((yyval.string), (yyvsp[0].string)); free((yyvsp[0].string));} #line 2686 "parse.c" break; case 103: #line 481 "parse.y" { (yyval.sl) = concat_string_lists((yyvsp[-2].sl), sl_from_str_consume((yyvsp[0].string))); } #line 2692 "parse.c" break; case 104: #line 483 "parse.y" { (yyval.sl) = sl_from_str_consume((yyvsp[0].string)); } #line 2698 "parse.c" break; case 105: #line 489 "parse.y" { if ((yyvsp[-3].av_flavor) != AV_RULE_ALLOW) { free_string_list((yyvsp[-2].sl)); free_string_list((yyvsp[-1].sl)); const struct location loc = { (yylsp[-3]).first_line, (yylsp[-3]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Incomplete AV rule"); YYERROR; } insert_role_allow(&cur, (yyvsp[-2].sl), (yyvsp[-1].sl), (yyloc).first_line); } #line 2711 "parse.c" break; case 106: #line 500 "parse.y" { insert_role_types(&cur, (yyvsp[-3].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-3].string)); } #line 2717 "parse.c" break; case 107: #line 505 "parse.y" { insert_type_transition(&cur, TT_TT, (yyvsp[-5].sl), (yyvsp[-4].sl), (yyvsp[-2].sl), (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2723 "parse.c" break; case 108: #line 508 "parse.y" { insert_type_transition(&cur, TT_TT, (yyvsp[-6].sl), (yyvsp[-5].sl), (yyvsp[-3].sl), (yyvsp[-2].string), (yyvsp[-1].string), (yyloc).first_line); free((yyvsp[-2].string)); free((yyvsp[-1].string)); } #line 2729 "parse.c" break; case 109: #line 510 "parse.y" { insert_type_transition(&cur, TT_TM, (yyvsp[-5].sl), (yyvsp[-4].sl), (yyvsp[-2].sl), (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2735 "parse.c" break; case 110: #line 512 "parse.y" { insert_type_transition(&cur, TT_TC, (yyvsp[-5].sl), (yyvsp[-4].sl), (yyvsp[-2].sl), (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2741 "parse.c" break; case 111: #line 516 "parse.y" { insert_type_transition(&cur, TT_RT, (yyvsp[-5].sl), (yyvsp[-4].sl), (yyvsp[-2].sl), (yyvsp[-1].string), NULL, (yyloc).first_line); free((yyvsp[-1].string)); } #line 2747 "parse.c" break; case 112: #line 520 "parse.y" { insert_role_transition(&cur, (yyvsp[-3].sl), (yyvsp[-2].sl), NULL, (yyvsp[-1].string), (yyloc).first_line); free((yyvsp[-1].string)); } #line 2753 "parse.c" break; case 113: #line 522 "parse.y" { insert_role_transition(&cur, (yyvsp[-5].sl), (yyvsp[-4].sl), (yyvsp[-2].sl), (yyvsp[-1].string), (yyloc).first_line); free((yyvsp[-1].string)); } #line 2759 "parse.c" break; case 114: #line 527 "parse.y" { insert_interface_call(&cur, (yyvsp[-3].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-3].string)); } #line 2765 "parse.c" break; case 115: #line 530 "parse.y" { insert_interface_call(&cur, (yyvsp[-2].string), NULL, (yyloc).first_line); free((yyvsp[-2].string)); } #line 2771 "parse.c" break; case 116: #line 535 "parse.y" { end_optional_policy(&cur); } #line 2777 "parse.c" break; case 117: #line 538 "parse.y" { end_optional_policy(&cur); } #line 2783 "parse.c" break; case 118: #line 541 "parse.y" { end_optional_policy(&cur); } #line 2789 "parse.c" break; case 119: #line 542 "parse.y" { begin_optional_else(&cur, (yyloc).first_line); } #line 2795 "parse.c" break; case 120: #line 543 "parse.y" { end_optional_else(&cur); } #line 2801 "parse.c" break; case 121: #line 547 "parse.y" { begin_optional_policy(&cur, (yyloc).first_line); save_command(cur->parent, (yyvsp[0].string)); free((yyvsp[0].string)); } #line 2807 "parse.c" break; case 122: #line 552 "parse.y" { end_gen_require(&cur, 0); save_command(cur, (yyvsp[-3].string)); free((yyvsp[-3].string)); } #line 2813 "parse.c" break; case 123: #line 555 "parse.y" { end_gen_require(&cur, 1); } #line 2819 "parse.c" break; case 124: #line 557 "parse.y" { begin_require(&cur, (yyloc).first_line); save_command(cur->parent, (yyvsp[0].string)); free((yyvsp[0].string)); } #line 2825 "parse.c" break; case 125: #line 558 "parse.y" { end_require(&cur); } #line 2831 "parse.c" break; case 126: #line 562 "parse.y" { begin_gen_require(&cur, (yyloc).first_line); save_command(cur->parent, (yyvsp[0].string)); free((yyvsp[0].string)); } #line 2837 "parse.c" break; case 129: #line 572 "parse.y" { save_command(cur, (yyvsp[0].string)); free((yyvsp[0].string)); } #line 2843 "parse.c" break; case 130: #line 576 "parse.y" { for (const struct string_list *iter = (yyvsp[-1].sl); iter; iter = iter->next) insert_declaration(&cur, DECL_TYPE, iter->string, NULL, (yyloc).first_line); free_string_list((yyvsp[-1].sl)); } #line 2852 "parse.c" break; case 131: #line 581 "parse.y" { for (const struct string_list *iter = (yyvsp[-1].sl); iter; iter = iter->next) insert_declaration(&cur, DECL_ATTRIBUTE, iter->string, NULL, (yyloc).first_line); free_string_list((yyvsp[-1].sl)); } #line 2861 "parse.c" break; case 132: #line 586 "parse.y" { for (const struct string_list *iter = (yyvsp[-1].sl); iter; iter = iter->next) insert_declaration(&cur, DECL_ROLE, iter->string, NULL, (yyloc).first_line); free_string_list((yyvsp[-1].sl)); } #line 2870 "parse.c" break; case 133: #line 591 "parse.y" { for (const struct string_list *iter = (yyvsp[-1].sl); iter; iter = iter->next) insert_declaration(&cur, DECL_ATTRIBUTE_ROLE, iter->string, NULL, (yyloc).first_line); free_string_list((yyvsp[-1].sl)); } #line 2879 "parse.c" break; case 134: #line 596 "parse.y" { for (const struct string_list *iter = (yyvsp[-1].sl); iter; iter = iter->next) insert_declaration(&cur, DECL_BOOL, iter->string, NULL, (yyloc).first_line); free_string_list((yyvsp[-1].sl)); } #line 2888 "parse.c" break; case 135: #line 601 "parse.y" { insert_declaration(&cur, DECL_CLASS, (yyvsp[-2].string), (yyvsp[-1].sl), (yyloc).first_line); free((yyvsp[-2].string)); } #line 2894 "parse.c" break; case 136: #line 603 "parse.y" { begin_ifdef(&cur, (yyloc).first_line); } #line 2900 "parse.c" break; case 137: #line 604 "parse.y" { end_ifdef(&cur); free((yyvsp[-7].string)); } #line 2906 "parse.c" break; case 138: #line 606 "parse.y" { begin_ifdef(&cur, (yyloc).first_line); } #line 2912 "parse.c" break; case 139: #line 607 "parse.y" { end_ifdef(&cur); free((yyvsp[-5].string)); } #line 2918 "parse.c" break; case 141: #line 613 "parse.y" { insert_m4simplemacro(&cur, (yyvsp[0].string), (yyloc).first_line); } #line 2924 "parse.c" break; case 146: #line 627 "parse.y" { begin_ifdef(&cur, (yyloc).first_line); } #line 2930 "parse.c" break; case 147: #line 628 "parse.y" { end_ifdef(&cur); free((yyvsp[-5].string)); } #line 2936 "parse.c" break; case 150: #line 638 "parse.y" { begin_ifelse(&cur, (yyloc).first_line); } #line 2942 "parse.c" break; case 151: #line 638 "parse.y" { end_ifelse(&cur); } #line 2948 "parse.c" break; case 157: #line 658 "parse.y" { free((yyvsp[0].string)); } #line 2954 "parse.c" break; case 167: #line 680 "parse.y" { free((yyvsp[0].string)); } #line 2960 "parse.c" break; case 175: #line 698 "parse.y" { begin_m4_argument(&cur, (yyloc).first_line); } #line 2966 "parse.c" break; case 176: #line 698 "parse.y" { end_m4_argument(&cur); } #line 2972 "parse.c" break; case 177: #line 700 "parse.y" { begin_m4_argument(&cur, (yyloc).first_line); } #line 2978 "parse.c" break; case 178: #line 700 "parse.y" { end_m4_argument(&cur); } #line 2984 "parse.c" break; case 182: #line 710 "parse.y" { free((yyvsp[0].string)); } #line 2990 "parse.c" break; case 184: #line 716 "parse.y" { (yyval.sl) = sl_from_str_consume((yyvsp[0].string)); } #line 2996 "parse.c" break; case 185: #line 718 "parse.y" { (yyval.sl) = sl_from_str_consume((yyvsp[-1].string)); } #line 3002 "parse.c" break; case 186: #line 720 "parse.y" { (yyval.sl) = sl_from_str(""); } #line 3008 "parse.c" break; case 188: #line 726 "parse.y" { (yyval.sl) = concat_string_lists((yyvsp[-2].sl), (yyvsp[0].sl)); } #line 3014 "parse.c" break; case 189: #line 728 "parse.y" { struct string_list *sl = calloc(1, sizeof(struct string_list)); sl->string = (yyvsp[0].string); sl->has_incorrect_space = 1; (yyval.sl) = concat_string_lists((yyvsp[-1].sl), sl); } #line 3023 "parse.c" break; case 190: #line 735 "parse.y" { size_t len = strlen((yyvsp[-2].string)) + strlen((yyvsp[0].string)) + 1 /* DASH */ + 1 /* NT */; (yyval.string) = malloc(len); snprintf((yyval.string), len, "%s-%s", (yyvsp[-2].string), (yyvsp[0].string)); free((yyvsp[-2].string)); free((yyvsp[0].string)); } #line 3032 "parse.c" break; case 193: #line 746 "parse.y" { size_t len = strlen((yyvsp[-2].string)) + strlen((yyvsp[0].string)) + 1 /* COLON */ + 1 /* NT */; (yyval.string) = malloc(len); snprintf((yyval.string), len, "%s:%s", (yyvsp[-2].string), (yyvsp[0].string)); free((yyvsp[-2].string)); free((yyvsp[0].string)); } #line 3041 "parse.c" break; case 195: #line 755 "parse.y" { size_t len = strlen((yyvsp[-2].string)) + strlen((yyvsp[0].string)) + 1 /* PERIOD */ + 1 /* NT */; (yyval.string) = malloc(len); snprintf((yyval.string), len, "%s.%s", (yyvsp[-2].string), (yyvsp[0].string)); free((yyvsp[-2].string)); free((yyvsp[0].string)); } #line 3050 "parse.c" break; case 198: #line 768 "parse.y" { end_boolean_policy(&cur); } #line 3056 "parse.c" break; case 199: #line 771 "parse.y" { end_boolean_policy(&cur); } #line 3062 "parse.c" break; case 200: #line 775 "parse.y" { begin_boolean_policy(&cur, (yyloc).first_line); save_command(cur->parent, (yyvsp[0].string)); free((yyvsp[0].string)); } #line 3068 "parse.c" break; case 201: #line 779 "parse.y" { begin_tunable_policy(&cur, (yyloc).first_line); } #line 3074 "parse.c" break; case 202: #line 780 "parse.y" { end_tunable_policy(&cur); } #line 3080 "parse.c" break; case 203: #line 782 "parse.y" { begin_tunable_policy(&cur, (yyloc).first_line); } #line 3086 "parse.c" break; case 204: #line 783 "parse.y" { end_tunable_policy(&cur); } #line 3092 "parse.c" break; case 205: #line 787 "parse.y" { free((yyvsp[-2].string)); free((yyvsp[-1].string)); } #line 3098 "parse.c" break; case 206: #line 789 "parse.y" { free((yyvsp[-2].string)); free((yyvsp[-1].string)); } #line 3104 "parse.c" break; case 209: #line 799 "parse.y" { free((yyvsp[-1].string)); } #line 3110 "parse.c" break; case 210: #line 803 "parse.y" { free((yyvsp[-2].string)); } #line 3116 "parse.c" break; case 211: #line 807 "parse.y" { free((yyvsp[0].string)); } #line 3122 "parse.c" break; case 212: #line 809 "parse.y" { free((yyvsp[0].string)); } #line 3128 "parse.c" break; case 213: #line 813 "parse.y" { free((yyvsp[-2].string)); free((yyvsp[0].string)); } #line 3134 "parse.c" break; case 214: #line 817 "parse.y" { free((yyvsp[-2].string)); } #line 3140 "parse.c" break; case 216: #line 825 "parse.y" { free((yyvsp[-1].string)); free((yyvsp[0].string)); } #line 3146 "parse.c" break; case 217: #line 827 "parse.y" { free((yyvsp[-1].string)); free((yyvsp[0].string)); } #line 3152 "parse.c" break; case 218: #line 831 "parse.y" { free((yyvsp[-2].string)); } #line 3158 "parse.c" break; case 219: #line 833 "parse.y" { free((yyvsp[-2].string)); } #line 3164 "parse.c" break; case 220: #line 835 "parse.y" { free((yyvsp[-2].string)); } #line 3170 "parse.c" break; case 221: #line 839 "parse.y" { begin_define(&cur, (yyloc).first_line); } #line 3176 "parse.c" break; case 222: #line 840 "parse.y" { end_define(&cur); } #line 3182 "parse.c" break; case 223: #line 844 "parse.y" { free((yyvsp[-1].string)); } #line 3188 "parse.c" break; case 224: #line 846 "parse.y" { free((yyvsp[0].string)); } #line 3194 "parse.c" break; case 229: #line 860 "parse.y" { free((yyvsp[0].string)); } #line 3200 "parse.c" break; case 231: #line 866 "parse.y" { (yyval.string) = strdup(""); } #line 3206 "parse.c" break; case 232: #line 870 "parse.y" { free((yyvsp[-7].string)); free((yyvsp[-6].string)); free_string_list((yyvsp[-5].sl)); free((yyvsp[-3].string)); free((yyvsp[-1].string)); } #line 3212 "parse.c" break; case 233: #line 872 "parse.y" { free((yyvsp[-9].string)); free((yyvsp[-8].string)); free_string_list((yyvsp[-7].sl)); free((yyvsp[-5].string)); free((yyvsp[-3].string)); free((yyvsp[-1].string)); } #line 3218 "parse.c" break; case 236: #line 880 "parse.y" { free((yyvsp[-1].string)); } #line 3224 "parse.c" break; case 237: #line 882 "parse.y" { free((yyvsp[-3].string)); free((yyvsp[-1].string)); } #line 3230 "parse.c" break; case 238: #line 884 "parse.y" { free((yyvsp[-2].string)); } #line 3236 "parse.c" break; case 239: #line 888 "parse.y" { free((yyvsp[-4].string)); free((yyvsp[-2].string)); free((yyvsp[0].string)); } #line 3242 "parse.c" break; case 240: #line 890 "parse.y" { free((yyvsp[-6].string)); free((yyvsp[-4].string)); free((yyvsp[-2].string)); free((yyvsp[0].string)); } #line 3248 "parse.c" break; case 241: #line 894 "parse.y" { insert_permissive_statement(&cur, (yyvsp[-1].string), (yyloc).first_line); free((yyvsp[-1].string));} #line 3254 "parse.c" break; case 242: #line 898 "parse.y" { free((yyvsp[-2].string)); free((yyvsp[-1].string)); } #line 3260 "parse.c" break; case 248: #line 920 "parse.y" { insert_comment(&cur, (yyloc).first_line); } #line 3266 "parse.c" break; case 249: #line 924 "parse.y" { save_command(cur, (yyvsp[-2].string)); free((yyvsp[-2].string)); } #line 3272 "parse.c" break; case 250: #line 926 "parse.y" { save_command(cur, (yyvsp[-1].string)); free((yyvsp[-1].string)); } #line 3278 "parse.c" break; case 251: #line 930 "parse.y" { if (expected_node_flavor != NODE_IF_FILE) { const struct location loc = { (yylsp[-6]).first_line, (yylsp[-6]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected if-file parsed"); YYERROR; } begin_interface_def(&cur, (yyvsp[-6].node_flavor), (yyvsp[-3].string), (yyloc).first_line); free((yyvsp[-3].string)); } #line 3290 "parse.c" break; case 252: #line 940 "parse.y" { end_interface_def(&cur); } #line 3296 "parse.c" break; case 253: #line 944 "parse.y" { (yyval.node_flavor) = NODE_INTERFACE_DEF; } #line 3302 "parse.c" break; case 254: #line 946 "parse.y" { (yyval.node_flavor) = NODE_TEMP_DEF; } #line 3308 "parse.c" break; case 261: #line 969 "parse.y" { if (expected_node_flavor != NODE_SPT_FILE) { free((yyvsp[-6].string)); free_string_list((yyvsp[-2].sl)); const struct location loc = { (yylsp[-9]).first_line, (yylsp[-9]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected spt-file parsed"); YYERROR; } if (ends_with((yyvsp[-6].string), strlen((yyvsp[-6].string)), "_perms", strlen("_perms"))) { insert_into_permmacros_map((yyvsp[-6].string), (yyvsp[-2].sl)); } else { free_string_list((yyvsp[-2].sl)); } free((yyvsp[-6].string)); } #line 3325 "parse.c" break; case 262: #line 982 "parse.y" { if (expected_node_flavor != NODE_SPT_FILE) { free((yyvsp[-7].string)); free_string_list((yyvsp[-3].sl)); const struct location loc = { (yylsp[-10]).first_line, (yylsp[-10]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected spt-file parsed"); YYERROR; } free((yyvsp[-7].string)); free_string_list((yyvsp[-3].sl)); } #line 3337 "parse.c" break; case 271: #line 1018 "parse.y" { if (expected_node_flavor != NODE_AV_FILE) { free((yyvsp[-1].string)); const struct location loc = { (yylsp[-2]).first_line, (yylsp[-2]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected av-file parsed"); YYERROR; } insert_into_decl_map((yyvsp[-1].string), "__av_file__", DECL_CLASS); free((yyvsp[-1].string)); } #line 3349 "parse.c" break; case 272: #line 1026 "parse.y" { if (expected_node_flavor != NODE_AV_FILE) { free((yyvsp[-2].string)); free((yyvsp[0].string)); const struct location loc = { (yylsp[-3]).first_line, (yylsp[-3]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected av-file parsed"); YYERROR; } insert_into_decl_map((yyvsp[-2].string), "__av_file__", DECL_CLASS); free((yyvsp[-2].string)); free((yyvsp[0].string)); } #line 3361 "parse.c" break; case 273: #line 1034 "parse.y" { if (expected_node_flavor != NODE_AV_FILE) { free((yyvsp[-3].string)); free((yyvsp[-1].string)); const struct location loc = { (yylsp[-4]).first_line, (yylsp[-4]).first_column, (yylsp[0]).last_line, (yylsp[0]).last_column }; yyerror(&loc, NULL, "Error: Unexpected av-file parsed"); YYERROR; } insert_into_decl_map((yyvsp[-3].string), "__av_file__", DECL_CLASS); free((yyvsp[-3].string)); free((yyvsp[-1].string)); } #line 3373 "parse.c" break; case 274: #line 1044 "parse.y" { free((yyvsp[-1].string)); } #line 3379 "parse.c" break; case 278: #line 1058 "parse.y" { insert_into_decl_map((yyvsp[0].string), "__av_file__", DECL_PERM); free((yyvsp[0].string)); } #line 3385 "parse.c" break; #line 3389 "parse.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; *++yylsp = yyloc; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (&yylloc, scanner, YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (&yylloc, scanner, yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } yyerror_range[1] = yylloc; if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, &yylloc, scanner); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yyerror_range[1] = *yylsp; yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp, scanner); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END yyerror_range[2] = yylloc; /* Using YYLLOC is tempting, but would change the location of the lookahead. YYLOC is available though. */ YYLLOC_DEFAULT (yyloc, yyerror_range, 2); *++yylsp = yyloc; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (&yylloc, scanner, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif /*-----------------------------------------------------. | yyreturn -- parsing is finished, return the result. | `-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, scanner); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[+*yyssp], yyvsp, yylsp, scanner); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 1063 "parse.y" static unsigned leading_spaces(const char *str) { unsigned result = 0; while (str[result] == ' ' || str[result] == '\t') result++; return result; } static void yyerror(const YYLTYPE *locp, __attribute__((unused)) yyscan_t scanner, char const *msg) { // Print error tag: """test7.if: 1: (F): Error: Unexpected te-file parsed (F-001)""" { struct check_result *res = make_check_result('F', F_ID_POLICY_SYNTAX, "%s", msg); res->lineno = locp->first_line; struct check_data data; data.mod_name = get_current_module_name(); char *copy = strdup(parsing_filename); data.filename = basename(copy); data.flavor = FILE_TE_FILE; // We don't know but it's unused by display_check_result display_check_result(res, &data); free(copy); free_check_result(res); } unsigned lines_to_print = locp->last_line - locp->first_line + 1; bool shortened = false; if (lines_to_print > LINES_TO_CACHE) { lines_to_print = LINES_TO_CACHE; shortened = true; printf("%5u | ... [truncated]\n", locp->last_line - LINES_TO_CACHE); } for (unsigned k = lines_to_print; k > 0; --k) { const char *current_line = trim_right(current_lines[(LINES_TO_CACHE + line_cache_index - k + 1) % LINES_TO_CACHE]); const unsigned current_first_column = (k == lines_to_print && !shortened) ? locp->first_column : (1 + leading_spaces(current_line)); const unsigned current_last_column = (k == 1) ? locp->last_column : (unsigned)strlen(current_line); printf("%5u |", locp->last_line - (k - 1)); // print line, replace tabs unsigned tabs_before_hinter = 0, tabs_inside_hinter = 0; if (*current_line != '\0') { printf(" "); } for (const char *c = current_line; *c != '\0'; ++c) { if (*c == '\t') { if ((size_t)(c - current_line) < current_first_column) { tabs_before_hinter++; } else if ((size_t)(c - current_line) < current_last_column) { tabs_inside_hinter++; } printf(" "); continue; } if (!isprint((unsigned char)*c) && !isspace((unsigned char)*c)) { printf("%s!%s\n%sWarning%s: Line in question contains unprintable character at position %zu: 0x%.2x\n", color_error(), color_reset(), color_warning(), color_reset(), (size_t)(c - current_line + 1), *c); return; } printf("%c", *c); } printf("\n | "); // print hinter for (unsigned i = 0; i < tabs_before_hinter; ++i) { printf(" "); } for (unsigned i = tabs_before_hinter + 1; i < current_first_column; ++i) { printf(" "); } if (k == lines_to_print) { printf("%s^", color_error()); } else { printf("%s~", color_error()); } if (current_last_column > current_first_column) { for (unsigned i = 0; i < (current_last_column - current_first_column); ++i) { printf("~"); } for (unsigned i = 0; i < tabs_inside_hinter; ++i) { printf("~~~"); } } printf("%s\n", color_reset()); } } struct policy_node *yyparse_wrapper(FILE *filefd, const char *filename, enum node_flavor expected_flavor) { struct policy_node *ast = calloc(1, sizeof(struct policy_node)); ast->flavor = expected_node_flavor = expected_flavor; yyscan_t scanner; yylex_init(&scanner); yyrestart(filefd, scanner); parsing_filename = filename; cur = ast; const int ret = yyparse(scanner); reset_current_lines(); yylex_destroy(scanner); if (ret != 0) { // parser will have printed an error message free_policy_node(ast); return NULL; } return ast; } selint-1.2.1/src/parse.h0000644000175100001710000001507614167117371012022 00000000000000/* A Bison parser, made by GNU Bison 3.5.1. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Undocumented macros, especially those whose name start with YY_, are private implementation details. Do not rely on them. */ #ifndef YY_YY_PARSE_H_INCLUDED # define YY_YY_PARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* "%code requires" blocks. */ #line 23 "parse.y" typedef void* yyscan_t; #line 52 "parse.h" /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { STRING = 258, NUM_STRING = 259, IPV4 = 260, IPV6 = 261, NUMBER = 262, QUOTED_STRING = 263, VERSION_NO = 264, SELINT_COMMAND = 265, UNKNOWN_TOKEN = 266, POLICY_MODULE = 267, MODULE = 268, TYPE = 269, TYPEALIAS = 270, ALIAS = 271, ATTRIBUTE = 272, BOOL = 273, TYPE_ATTRIBUTE = 274, ROLE_ATTRIBUTE = 275, ROLE = 276, TYPES = 277, ATTRIBUTE_ROLE = 278, ALLOW = 279, ALLOW_XPERM = 280, AUDIT_ALLOW = 281, AUDIT_ALLOW_XPERM = 282, DONT_AUDIT = 283, DONT_AUDIT_XPERM = 284, NEVER_ALLOW = 285, NEVER_ALLOW_XPERM = 286, TYPE_TRANSITION = 287, TYPE_MEMBER = 288, TYPE_CHANGE = 289, RANGE_TRANSITION = 290, ROLE_TRANSITION = 291, OPTIONAL_POLICY = 292, GEN_REQUIRE = 293, GEN_BOOL = 294, GEN_TUNABLE = 295, REQUIRE = 296, TUNABLE_POLICY = 297, IFELSE = 298, REFPOLICYWARN = 299, CLASS = 300, COMMON = 301, INHERITS = 302, IFDEF = 303, IFNDEF = 304, IF = 305, ELSE = 306, GENFSCON = 307, SID = 308, PORTCON = 309, NETIFCON = 310, NODECON = 311, FS_USE_TRANS = 312, FS_USE_XATTR = 313, FS_USE_TASK = 314, DEFINE = 315, GEN_USER = 316, GEN_CONTEXT = 317, PERMISSIVE = 318, TYPEBOUNDS = 319, INTERFACE = 320, TEMPLATE = 321, USERDEBUG_OR_ENG = 322, FILE_TYPE_SPECIFIER = 323, OPEN_PAREN = 324, COMMA = 325, PERIOD = 326, CLOSE_PAREN = 327, OPEN_CURLY = 328, CLOSE_CURLY = 329, COLON = 330, SEMICOLON = 331, BACKTICK = 332, SINGLE_QUOTE = 333, TILDA = 334, STAR = 335, DASH = 336, AND = 337, OR = 338, XOR = 339, NOT = 340, EQUAL = 341, NOT_EQUAL = 342, COMMENT = 343 }; #endif /* Tokens. */ #define STRING 258 #define NUM_STRING 259 #define IPV4 260 #define IPV6 261 #define NUMBER 262 #define QUOTED_STRING 263 #define VERSION_NO 264 #define SELINT_COMMAND 265 #define UNKNOWN_TOKEN 266 #define POLICY_MODULE 267 #define MODULE 268 #define TYPE 269 #define TYPEALIAS 270 #define ALIAS 271 #define ATTRIBUTE 272 #define BOOL 273 #define TYPE_ATTRIBUTE 274 #define ROLE_ATTRIBUTE 275 #define ROLE 276 #define TYPES 277 #define ATTRIBUTE_ROLE 278 #define ALLOW 279 #define ALLOW_XPERM 280 #define AUDIT_ALLOW 281 #define AUDIT_ALLOW_XPERM 282 #define DONT_AUDIT 283 #define DONT_AUDIT_XPERM 284 #define NEVER_ALLOW 285 #define NEVER_ALLOW_XPERM 286 #define TYPE_TRANSITION 287 #define TYPE_MEMBER 288 #define TYPE_CHANGE 289 #define RANGE_TRANSITION 290 #define ROLE_TRANSITION 291 #define OPTIONAL_POLICY 292 #define GEN_REQUIRE 293 #define GEN_BOOL 294 #define GEN_TUNABLE 295 #define REQUIRE 296 #define TUNABLE_POLICY 297 #define IFELSE 298 #define REFPOLICYWARN 299 #define CLASS 300 #define COMMON 301 #define INHERITS 302 #define IFDEF 303 #define IFNDEF 304 #define IF 305 #define ELSE 306 #define GENFSCON 307 #define SID 308 #define PORTCON 309 #define NETIFCON 310 #define NODECON 311 #define FS_USE_TRANS 312 #define FS_USE_XATTR 313 #define FS_USE_TASK 314 #define DEFINE 315 #define GEN_USER 316 #define GEN_CONTEXT 317 #define PERMISSIVE 318 #define TYPEBOUNDS 319 #define INTERFACE 320 #define TEMPLATE 321 #define USERDEBUG_OR_ENG 322 #define FILE_TYPE_SPECIFIER 323 #define OPEN_PAREN 324 #define COMMA 325 #define PERIOD 326 #define CLOSE_PAREN 327 #define OPEN_CURLY 328 #define CLOSE_CURLY 329 #define COLON 330 #define SEMICOLON 331 #define BACKTICK 332 #define SINGLE_QUOTE 333 #define TILDA 334 #define STAR 335 #define DASH 336 #define AND 337 #define OR 338 #define XOR 339 #define NOT 340 #define EQUAL 341 #define NOT_EQUAL 342 #define COMMENT 343 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 50 "parse.y" char *string; char symbol; struct string_list *sl; enum av_rule_flavor av_flavor; enum node_flavor node_flavor; #line 247 "parse.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif /* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE YYLTYPE; struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; }; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif int yyparse (yyscan_t scanner); /* "%code provides" blocks. */ #line 75 "parse.y" // number of lines stored, printed on parse errors for multiline statements #define LINES_TO_CACHE 5 // global prototype struct policy_node *yyparse_wrapper(FILE *filefd, const char *filename, enum node_flavor expected_flavor); #line 281 "parse.h" #endif /* !YY_YY_PARSE_H_INCLUDED */ selint-1.2.1/src/parse_functions.c0000644000175100001710000005241214167117255014101 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "parse_functions.h" #include "selint_error.h" #include "tree.h" #include "template.h" #include "util.h" #include "perm_macro.h" char *module_name = NULL; enum selint_error insert_header(struct policy_node **cur, const char *mn, enum header_flavor flavor, unsigned int lineno) { struct header_data *data = (struct header_data *)malloc(sizeof(struct header_data)); if (!data) { return SELINT_OUT_OF_MEM; } memset(data, 0, sizeof(struct header_data)); data->flavor = flavor; data->module_name = strdup(mn); if (!data->module_name) { free(data); return SELINT_OUT_OF_MEM; } union node_data nd; nd.h_data = data; enum selint_error ret = insert_policy_node_next(*cur, NODE_HEADER, nd, lineno); if (ret != SELINT_SUCCESS) { return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } void set_current_module_name(const char *mn) { if (module_name != NULL) { free(module_name); } module_name = strdup(mn); } char *get_current_module_name() { return module_name; } enum selint_error insert_comment(struct policy_node **cur, unsigned int lineno) { union node_data data; data.str = NULL; enum selint_error ret = insert_policy_node_next(*cur, NODE_COMMENT, data, lineno); if (ret != SELINT_SUCCESS) { return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_declaration(struct policy_node **cur, enum decl_flavor flavor, const char *name, struct string_list *attrs, unsigned int lineno) { if (!is_in_require(*cur)) { // In a require block, the objects aren't being declared // Otherwise, we need to insert them into the appropriate map const char *temp_name = get_name_if_in_template(*cur); if (temp_name) { // We are inside a template, so we need to save declarations in the template map // 'role foo types bar_t, baz_t;' statements are not declarations. insert_decl_into_template_map(temp_name, flavor, name); } else if ('$' != name[0]) { // If the name starts with $ we're probably doing something like associating // a role with types in interfaces char *mn = get_current_module_name(); if (!mn) { return SELINT_NO_MOD_NAME; } insert_into_decl_map(name, mn, flavor); } } struct declaration_data *data = (struct declaration_data *)malloc(sizeof(struct declaration_data)); if (!data) { return SELINT_OUT_OF_MEM; } memset(data, 0, sizeof(struct declaration_data)); data->flavor = flavor; data->name = strdup(name); data->attrs = attrs; union node_data nd; nd.d_data = data; enum selint_error ret = insert_policy_node_next(*cur, NODE_DECL, nd, lineno); if (ret != SELINT_SUCCESS) { free(data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_aliases(struct policy_node **cur, struct string_list *aliases, enum decl_flavor flavor, unsigned int lineno) { struct string_list *alias = aliases; while (alias) { const char *temp_name = get_name_if_in_template(*cur); if (temp_name) { insert_decl_into_template_map(temp_name, flavor, alias->string); } else { char *mn = get_current_module_name(); if (!mn) { free_string_list(aliases); return SELINT_NO_MOD_NAME; } insert_into_decl_map(alias->string, mn, flavor); } union node_data nd; nd.str = strdup(alias->string); enum selint_error ret = insert_policy_node_child(*cur, NODE_ALIAS, nd, lineno); if (ret != SELINT_SUCCESS) { return ret; } alias = alias->next; } free_string_list(aliases); return SELINT_SUCCESS; } enum selint_error insert_type_alias(struct policy_node **cur, const char *type, unsigned int lineno) { union node_data nd; nd.str = strdup(type); enum selint_error ret = insert_policy_node_next(*cur, NODE_TYPE_ALIAS, nd, lineno); if (ret != SELINT_SUCCESS) { return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_av_rule(struct policy_node **cur, enum av_rule_flavor flavor, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, struct string_list *perms, unsigned int lineno) { struct av_rule_data *av_data = malloc(sizeof(struct av_rule_data)); av_data->flavor = flavor; av_data->sources = sources; av_data->targets = targets; av_data->object_classes = object_classes; av_data->perms = perms; union node_data nd; nd.av_data = av_data; if ((*cur)->parent && (*cur)->parent->flavor == NODE_INTERFACE_DEF && str_in_sl("associate", perms)) { mark_transform_if((*cur)->parent->data.str); } enum selint_error ret = insert_policy_node_next(*cur, NODE_AV_RULE, nd, lineno); if (ret != SELINT_SUCCESS) { free_av_rule_data(av_data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_xperm_av_rule(struct policy_node **cur, enum av_rule_flavor flavor, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, const char *operation, struct string_list *perms, unsigned int lineno) { struct xav_rule_data *xav_data = malloc(sizeof(struct xav_rule_data)); xav_data->flavor = flavor; xav_data->sources = sources; xav_data->targets = targets; xav_data->object_classes = object_classes; xav_data->operation = strdup(operation); xav_data->perms = perms; union node_data nd; nd.xav_data = xav_data; enum selint_error ret = insert_policy_node_next(*cur, NODE_XAV_RULE, nd, lineno); if (ret != SELINT_SUCCESS) { free_xav_rule_data(xav_data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_role_allow(struct policy_node **cur, struct string_list *from_roles, struct string_list *to_roles, unsigned int lineno) { struct role_allow_data *ra_data = malloc(sizeof(struct role_allow_data)); ra_data->from = from_roles; ra_data->to = to_roles; union node_data nd; nd.ra_data = ra_data; enum selint_error ret = insert_policy_node_next(*cur, NODE_ROLE_ALLOW, nd, lineno); if (ret != SELINT_SUCCESS) { free_ra_data(ra_data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_role_types(struct policy_node **cur, const char *role, struct string_list *types, unsigned int lineno) { if ((*cur)->parent && (*cur)->parent->flavor == NODE_INTERFACE_DEF) { const struct string_list *cur_sl_item = types; while (cur_sl_item) { if (cur_sl_item->string[0] == '$') { // Role interfaces are only those where the types are passed in, not the roles mark_role_if((*cur)->parent->data.str); break; } cur_sl_item = cur_sl_item->next; } } struct role_types_data *rtyp_data = (struct role_types_data *)malloc(sizeof(struct role_types_data)); rtyp_data->role = strdup(role); rtyp_data->types = types; union node_data nd; nd.rtyp_data = rtyp_data; enum selint_error ret = insert_policy_node_next(*cur, NODE_ROLE_TYPES, nd, lineno); if (ret != SELINT_SUCCESS) { free_rtyp_data(rtyp_data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_type_transition(struct policy_node **cur, enum tt_flavor flavor, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, const char *default_type, const char *name, unsigned int lineno) { struct type_transition_data *tt_data = malloc(sizeof(struct type_transition_data)); tt_data->sources = sources; tt_data->targets = targets; tt_data->object_classes = object_classes; tt_data->default_type = strdup(default_type); if (name) { tt_data->name = strdup(name); } else { tt_data->name = NULL; } tt_data->flavor = flavor; if (!str_in_sl("process", object_classes) && (*cur)->parent && (*cur)->parent->flavor == NODE_INTERFACE_DEF) { mark_filetrans_if((*cur)->parent->data.str); } union node_data nd; nd.tt_data = tt_data; enum selint_error ret = insert_policy_node_next(*cur, NODE_TT_RULE, nd, lineno); if (ret != SELINT_SUCCESS) { free_type_transition_data(tt_data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_role_transition(struct policy_node **cur, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, char *default_role, unsigned int lineno) { struct role_transition_data *rt_data = malloc(sizeof(struct role_transition_data)); rt_data->sources = sources; rt_data->targets = targets; rt_data->object_classes = object_classes; rt_data->default_role = strdup(default_role); union node_data nd; nd.rt_data = rt_data; enum selint_error ret = insert_policy_node_next(*cur, NODE_RT_RULE, nd, lineno); if (ret != SELINT_SUCCESS) { free_role_transition_data(rt_data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } static int is_filetrans_if_name(const char *if_name) { if (0 == strcmp(if_name, "filetrans_pattern")) { return 1; } if (0 == strcmp(if_name, "filetrans_add_pattern")) { return 1; } const char *suffix = strrchr(if_name, '_'); if (suffix && (0 == strcmp(suffix, "_filetrans"))) { return 1; } return 0; } enum selint_error insert_interface_call(struct policy_node **cur, const char *if_name, struct string_list *args, unsigned int lineno) { struct if_call_data *if_data = malloc(sizeof(struct if_call_data)); if_data->name = strdup(if_name); if_data->args = args; const char *template_name = get_name_if_in_template(*cur); if (template_name) { insert_call_into_template_map(template_name, if_data); } else { enum selint_error r = add_template_declarations(if_name, args, NULL, module_name); if (r != SELINT_SUCCESS) { free_if_call_data(if_data); return r; } } if (is_filetrans_if_name(if_name) && (*cur)->parent && (*cur)->parent->flavor == NODE_INTERFACE_DEF) { mark_filetrans_if((*cur)->parent->data.str); } union node_data nd; nd.ic_data = if_data; enum selint_error ret = insert_policy_node_next(*cur, NODE_IF_CALL, nd, lineno); if (ret != SELINT_SUCCESS) { free_if_call_data(if_data); return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_permissive_statement(struct policy_node **cur, const char *domain, unsigned int lineno) { union node_data nd; nd.str = strdup(domain); enum selint_error ret = insert_policy_node_next(*cur, NODE_PERMISSIVE, nd, lineno); if (ret != SELINT_SUCCESS) { return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_semicolon(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; enum selint_error ret = insert_policy_node_next(*cur, NODE_SEMICOLON, nd, lineno); if (ret != SELINT_SUCCESS) { return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } enum selint_error insert_m4simplemacro(struct policy_node **cur, char *name, unsigned int lineno) { union node_data nd; nd.str = name; enum selint_error ret = insert_policy_node_next(*cur, NODE_M4_SIMPLE_MACRO, nd, lineno); if (ret != SELINT_SUCCESS) { return ret; } *cur = (*cur)->next; return SELINT_SUCCESS; } static enum selint_error begin_block(struct policy_node **cur, enum node_flavor block_type, union node_data nd, unsigned int lineno) { enum selint_error ret = insert_policy_node_next(*cur, block_type, nd, lineno); if (ret != SELINT_SUCCESS) { return ret; } *cur = (*cur)->next; nd.str = NULL; ret = insert_policy_node_child(*cur, NODE_START_BLOCK, nd, lineno); if (ret != SELINT_SUCCESS) { *cur = (*cur)->prev; free_policy_node((*cur)->next); return ret; } *cur = (*cur)->first_child; return SELINT_SUCCESS; } static enum selint_error end_block(struct policy_node **cur, enum node_flavor block_type) { if ((*cur)->parent == NULL || (*cur)->parent->flavor != block_type) { return SELINT_NOT_IN_BLOCK; } *cur = (*cur)->parent; return SELINT_SUCCESS; } enum selint_error begin_define(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_DEFINE, nd, lineno); } enum selint_error end_define(struct policy_node **cur) { return end_block(cur, NODE_DEFINE); } enum selint_error begin_optional_policy(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_OPTIONAL_POLICY, nd, lineno); } enum selint_error end_optional_policy(struct policy_node **cur) { return end_block(cur, NODE_OPTIONAL_POLICY); } enum selint_error begin_optional_else(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_OPTIONAL_ELSE, nd, lineno); } enum selint_error end_optional_else(struct policy_node **cur) { return end_block(cur, NODE_OPTIONAL_ELSE); } enum selint_error begin_boolean_policy(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_BOOLEAN_POLICY, nd, lineno); } enum selint_error end_boolean_policy(struct policy_node **cur) { return end_block(cur, NODE_BOOLEAN_POLICY); } enum selint_error begin_tunable_policy(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_TUNABLE_POLICY, nd, lineno); } enum selint_error end_tunable_policy(struct policy_node **cur) { return end_block(cur, NODE_TUNABLE_POLICY); } enum selint_error begin_interface_def(struct policy_node **cur, enum node_flavor flavor, const char *name, unsigned int lineno) { switch (flavor) { case NODE_INTERFACE_DEF: break; case NODE_TEMP_DEF: insert_template_into_template_map(name); break; default: return SELINT_BAD_ARG; } insert_into_ifs_map(name, get_current_module_name()); union node_data nd; nd.str = strdup(name); return begin_block(cur, flavor, nd, lineno); } enum selint_error end_interface_def(struct policy_node **cur) { if (end_block(cur, NODE_INTERFACE_DEF) == SELINT_NOT_IN_BLOCK) { return end_block(cur, NODE_TEMP_DEF); } else { return SELINT_SUCCESS; } } enum selint_error begin_gen_require(struct policy_node **cur, unsigned int lineno) { struct gen_require_data *data = (struct gen_require_data *)malloc(sizeof(struct gen_require_data)); union node_data nd; nd.gr_data = data; return begin_block(cur, NODE_GEN_REQ, nd, lineno); } enum selint_error end_gen_require(struct policy_node **cur, unsigned char unquoted) { if ((*cur)->parent && (*cur)->parent->flavor == NODE_GEN_REQ) { (*cur)->parent->data.gr_data->unquoted = unquoted; } return end_block(cur, NODE_GEN_REQ); } enum selint_error begin_require(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_REQUIRE, nd, lineno); } enum selint_error end_require(struct policy_node **cur) { return end_block(cur, NODE_REQUIRE); } enum selint_error begin_ifdef(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_IFDEF, nd, lineno); } enum selint_error end_ifdef(struct policy_node **cur) { return end_block(cur, NODE_IFDEF); } enum selint_error begin_ifelse(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_IFELSE, nd, lineno); } enum selint_error end_ifelse(struct policy_node **cur) { return end_block(cur, NODE_IFELSE); } enum selint_error begin_m4_argument(struct policy_node **cur, unsigned int lineno) { union node_data nd; nd.str = NULL; return begin_block(cur, NODE_M4_ARG, nd, lineno); } enum selint_error end_m4_argument(struct policy_node **cur) { return end_block(cur, NODE_M4_ARG); } enum selint_error save_command(struct policy_node *cur, const char *comm) { if (cur == NULL) { return SELINT_BAD_ARG; } if (comm == NULL) { return SELINT_SUCCESS; } while (*comm != 's' && *comm != '\0') { comm++; } if (0 != strncmp("selint-", comm, 7)) { return SELINT_PARSE_ERROR; } comm += strlen("selint-"); if (0 == strncmp("disable:", comm, 8)) { cur->exceptions = strdup(comm + strlen("disable:")); } else { return SELINT_PARSE_ERROR; } return SELINT_SUCCESS; } static enum node_flavor attr_to_node_flavor(enum attr_flavor flavor) { switch (flavor) { case ATTR_TYPE: return NODE_TYPE_ATTRIBUTE; case ATTR_ROLE: return NODE_ROLE_ATTRIBUTE; default: // Should never happen return NODE_ERROR; } } static enum selint_error insert_attribute(struct policy_node **cur, enum attr_flavor flavor, const char *type, struct string_list *attrs, unsigned int lineno) { struct attribute_data *data = calloc(1, sizeof(struct attribute_data)); if (!data) { return SELINT_OUT_OF_MEM; } union node_data nd; nd.at_data = data; data->type = strdup(type); data->attrs = attrs; data->flavor = flavor; enum selint_error ret = insert_policy_node_next(*cur, attr_to_node_flavor(flavor), nd, lineno); if (ret != SELINT_SUCCESS) { free(data); return ret; } *cur = (*cur)->next; if ((*cur)->parent && (*cur)->parent->flavor == NODE_INTERFACE_DEF && (is_transform_interface((*cur)->parent->data.str) || 0 == strcmp(get_current_module_name(), "mls") || 0 == strcmp(get_current_module_name(), "mcs"))) { mark_transform_if((*cur)->parent->data.str); } return SELINT_SUCCESS; } enum selint_error insert_type_attribute(struct policy_node **cur, const char *type, struct string_list *attrs, unsigned int lineno) { return insert_attribute(cur, ATTR_TYPE, type, attrs, lineno); } enum selint_error insert_role_attribute(struct policy_node **cur, const char *role, struct string_list *attrs, unsigned int lineno) { return insert_attribute(cur, ATTR_ROLE, role, attrs, lineno); } void cleanup_parsing() { if (module_name) { free(module_name); module_name = NULL; } free_permmacros(); free_all_maps(); } selint-1.2.1/src/selint_config.c0000644000175100001710000002073414167117255013524 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "util.h" #include "selint_config.h" #define READ_STRING_LIST_FROM_CONFIG(slp, config_name) \ if (slp) { \ struct string_list *end = NULL; \ for (unsigned int i = 0; i < cfg_size(cfg, config_name); i++) { \ struct string_list *cur = sl_from_str(cfg_getnstr(cfg, config_name, i)); \ if (!end) { \ *slp = end = cur; \ } else { \ end->next = cur; \ end = end->next; \ } \ } \ } \ static enum selint_error parse_bool(const char *string, bool *value) { if (0 == strcmp("true", string) || 0 == strcmp("True", string) || 0 == strcmp("TRUE", string) || 0 == strcmp("yes", string) || 0 == strcmp("Yes", string) || 0 == strcmp("YES", string)) { *value = true; return SELINT_SUCCESS; } if (0 == strcmp("false", string) || 0 == strcmp("False", string) || 0 == strcmp("FALSE", string) || 0 == strcmp("no", string) || 0 == strcmp("No", string) || 0 == strcmp("NO", string)) { *value = false; return SELINT_SUCCESS; } return SELINT_CONFIG_PARSE_ERROR; } static void insert_config_declarations(cfg_t * cfg, const char *config_item, enum decl_flavor flavor) { for (unsigned int i = 0; i < cfg_size(cfg, config_item); i++) { insert_into_decl_map(cfg_getnstr(cfg, config_item, i), "__assumed__", flavor); } } enum selint_error parse_config(const char *config_filename, int in_source_mode, char *severity, struct string_list **config_disabled_checks, struct string_list **config_enabled_checks, struct string_list **custom_fc_macros, struct config_check_data *config_check_data) { IGNORE_CONST_DISCARD_BEGIN; cfg_opt_t opts[] = { CFG_STR("severity", "convention", CFGF_NONE), CFG_STR_LIST("disable", "{}", CFGF_NONE), CFG_STR_LIST("enable_normal", "{}", CFGF_NONE), CFG_STR_LIST("enable_source", "{}", CFGF_NONE), CFG_STR_LIST("assume_users", "{}", CFGF_NONE), CFG_STR_LIST("assume_roles", "{}", CFGF_NONE), CFG_STR_LIST("custom_fc_macros", "{}", CFGF_NONE), CFG_STR_LIST("custom_te_simple_macros", "{}", CFGF_NONE), CFG_STR("ordering_rules", "refpolicy-lax", CFGF_NONE), CFG_STR_LIST("ordering_requires", "{ bool, class, role, attribute_role, attribute, type }", CFGF_NONE), CFG_STR("ordering_requires_same_flavor", "true", CFGF_NONE), CFG_STR("skip_checking_generated_fcs", "true", CFGF_NONE), CFG_END() }; IGNORE_CONST_DISCARD_END; cfg_t *cfg; cfg = cfg_init(opts, CFGF_NONE); print_if_verbose("Loading configuration from: %s\n", config_filename); if (cfg_parse(cfg, config_filename) == CFG_PARSE_ERROR) { printf ("Parse error when attempting to parse configuration file.\n"); cfg_free(cfg); return SELINT_CONFIG_PARSE_ERROR; } // Not specified on command line. Read from config const char *config_severity = cfg_getstr(cfg, "severity"); if (strcmp(config_severity, "convention") == 0) { *severity = 'C'; } else if (strcmp(config_severity, "style") == 0) { *severity = 'S'; } else if (strcmp(config_severity, "warning") == 0) { *severity = 'W'; } else if (strcmp(config_severity, "error") == 0) { *severity = 'E'; } else if (strcmp(config_severity, "fatal") == 0) { *severity = 'F'; } else { printf ("Invalid severity level (%s) specified in config.\n"\ "Options are \"convention\", \"style\", \"warning\", \"error\" and \"fatal\"\n", config_severity); cfg_free(cfg); return SELINT_CONFIG_PARSE_ERROR; } READ_STRING_LIST_FROM_CONFIG(config_disabled_checks, "disable") if (in_source_mode) { READ_STRING_LIST_FROM_CONFIG(config_enabled_checks, "enable_source") } else { READ_STRING_LIST_FROM_CONFIG(config_enabled_checks, "enable_normal") } insert_config_declarations(cfg, "assume_users", DECL_USER); insert_config_declarations(cfg, "assume_roles", DECL_ROLE); READ_STRING_LIST_FROM_CONFIG(custom_fc_macros, "custom_fc_macros"); READ_STRING_LIST_FROM_CONFIG(&(config_check_data->custom_te_simple_macros), "custom_te_simple_macros"); const char *config_ordering_rules = cfg_getstr(cfg, "ordering_rules"); if (strcmp(config_ordering_rules, "refpolicy") == 0) { config_check_data->order_conf = ORDER_REF; } else if (strcmp(config_ordering_rules, "refpolicy-light") == 0) { config_check_data->order_conf = ORDER_LIGHT; } else if (strcmp(config_ordering_rules, "refpolicy-lax") == 0) { config_check_data->order_conf = ORDER_LAX; } else { printf("Invalid ordering rules (%s) specified in config.\n"\ "Options are \"refpolicy\", \"refpolicy-light\"\n"\ "and \"refpolicy-lax\"\n", config_ordering_rules); cfg_free(cfg); return SELINT_CONFIG_PARSE_ERROR; } // ordering_requires const unsigned count = cfg_size(cfg, "ordering_requires"); if (count != 6) { printf("Incorrect amount of ordering_requires flavors (%u) specified in config.\n"\ "The required amount is 6.\n", count); cfg_free(cfg); return SELINT_CONFIG_PARSE_ERROR; } for (unsigned i = 0; i < 6; ++i) { const char *cfg_flavor = cfg_getnstr(cfg, "ordering_requires", i); enum decl_flavor parsed_flavor; if (0 == strcmp("attribute", cfg_flavor)) { parsed_flavor = DECL_ATTRIBUTE; } else if (0 == strcmp("attribute_role", cfg_flavor)) { parsed_flavor = DECL_ATTRIBUTE_ROLE; } else if (0 == strcmp("bool", cfg_flavor)) { parsed_flavor = DECL_BOOL; } else if (0 == strcmp("class", cfg_flavor)) { parsed_flavor = DECL_CLASS; } else if (0 == strcmp("role", cfg_flavor)) { parsed_flavor = DECL_ROLE; } else if (0 == strcmp("type", cfg_flavor)) { parsed_flavor = DECL_TYPE; } else { printf("Invalid ordering_requires flavor (%s) specified in config.\n"\ "See configuration file for available options\n", cfg_flavor); cfg_free(cfg); return SELINT_CONFIG_PARSE_ERROR; } for (unsigned j = 0; j < i; ++j) { if (config_check_data->order_requires[j] == parsed_flavor) { printf("Duplicate ordering_requires flavor (%s) specified in config.\n", cfg_flavor); cfg_free(cfg); return SELINT_CONFIG_PARSE_ERROR; } } config_check_data->order_requires[i] = parsed_flavor; } // ordering_requires_same_flavor const char *config_ordering_requires_same_flavor = cfg_getstr(cfg, "ordering_requires_same_flavor"); bool ordering_requires_same_flavor; enum selint_error r = parse_bool(config_ordering_requires_same_flavor, &ordering_requires_same_flavor); if (r != SELINT_SUCCESS) { printf("Invalid ordering_requires_same_flavor setting (%s) specified in config.\n"\ "Options are \"true\" and \"false\"\n", config_ordering_requires_same_flavor); cfg_free(cfg); return r; } config_check_data->ordering_requires_same_flavor = ordering_requires_same_flavor; // skip_checking_generated_fcs const char *config_skip_checking_generated_fcs = cfg_getstr(cfg, "skip_checking_generated_fcs"); bool skip_checking_generated_fcs; r = parse_bool(config_skip_checking_generated_fcs, &skip_checking_generated_fcs); if (r != SELINT_SUCCESS) { printf("Invalid skip_checking_generated_fcs setting (%s) specified in config.\n"\ "Options are \"true\" and \"false\"\n", config_skip_checking_generated_fcs); cfg_free(cfg); return r; } config_check_data->skip_checking_generated_fcs = skip_checking_generated_fcs; cfg_free(cfg); return SELINT_SUCCESS; } void free_selint_config(struct config_check_data *config_check_data) { if (!config_check_data) { return; } free_string_list(config_check_data->custom_te_simple_macros); } selint-1.2.1/src/string_list.c0000644000175100001710000000565514167117255013247 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "string_list.h" int str_in_sl(const char *str, const struct string_list *sl) { if (!sl) { return 0; } while (sl) { if (0 == strcmp(sl->string, str)) { return 1; } sl = sl->next; } return 0; } struct string_list *copy_string_list(const struct string_list *sl) { if (!sl) { return NULL; } struct string_list *ret = malloc(sizeof(struct string_list)); struct string_list *cur = ret; while (sl) { cur->string = strdup(sl->string); cur->has_incorrect_space = sl->has_incorrect_space; if (sl->next) { cur->next = malloc(sizeof(struct string_list)); } else { cur->next = NULL; } sl = sl->next; cur = cur->next; } return ret; } struct string_list *sl_from_str(const char *string) { struct string_list *ret = malloc(sizeof(struct string_list)); ret->string = strdup(string); ret->next = NULL; ret->has_incorrect_space = 0; return ret; } struct string_list *sl_from_strn(const char *string, size_t len) { struct string_list *ret = malloc(sizeof(struct string_list)); ret->string = strndup(string, len); ret->next = NULL; ret->has_incorrect_space = 0; return ret; } struct string_list *sl_from_str_consume(char *string) { struct string_list *ret = malloc(sizeof(struct string_list)); ret->string = string; ret->next = NULL; ret->has_incorrect_space = 0; return ret; } struct string_list *sl_from_strs(int count, ...) { struct string_list *ret = NULL; va_list args; va_start(args, count); for (int i = 0; i < count; ++i) { ret = concat_string_lists(ret, sl_from_str(va_arg(args, const char *))); } va_end(args); return ret; } struct string_list *concat_string_lists(struct string_list *head, struct string_list *tail) { if (!head) { return tail; } if (!tail) { return head; } struct string_list *cur = head; while (cur->next) { cur = cur->next; } cur->next = tail; return head; } enum selint_error append_to_sl(struct string_list *sl, const char *string) { if (!sl) { return SELINT_BAD_ARG; } while (sl->next) { sl = sl->next; } sl->next = sl_from_str(string); return SELINT_SUCCESS; } void free_string_list(struct string_list *list) { if (list == NULL) { return; } struct string_list *cur = list; while (cur) { struct string_list *to_free = cur; cur = cur->next; free(to_free->string); free(to_free); } } selint-1.2.1/src/util.c0000644000175100001710000000234314167117255011652 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "util.h" int verbose_flag; void print_if_verbose(const char *format, ...) { if (!verbose_flag) { return; } va_list args; va_start(args, format); vprintf(format, args); va_end(args); } bool ends_with(const char *str, size_t str_len, const char *suffix, size_t suffix_len) { if (str_len < suffix_len) { return 0; } return (0 == strncmp(str + str_len - suffix_len, suffix, suffix_len)); } char* trim_right(char *str) { size_t len = strlen(str); while (len > 0 && isspace((unsigned char)str[len-1])) { str[len-1] = '\0'; len--; } return str; } selint-1.2.1/src/selint_error.h0000644000175100001710000000155714167117255013417 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SELINT_ERROR_H #define SELINT_ERROR_H enum selint_error { SELINT_SUCCESS, SELINT_BAD_ARG, SELINT_OUT_OF_MEM, SELINT_NO_MOD_NAME, SELINT_NOT_IN_BLOCK, SELINT_IF_CALL_LOOP, SELINT_PARSE_ERROR, SELINT_M4_SUB_FAILURE, SELINT_CONFIG_PARSE_ERROR, SELINT_IO_ERROR }; #endif selint-1.2.1/src/check_hooks.h0000644000175100001710000001570114167117255013164 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CHECK_HOOKS_H #define CHECK_HOOKS_H #include "tree.h" #include "selint_error.h" #include "selint_config.h" enum convention_ids { C_ID_TE_ORDER = 1, C_ID_IF_COMMENT = 4, C_ID_UNORDERED_PERM = 5, C_ID_UNORDERED_REQ = 6, C_ID_SELF = 7, C_END }; enum style_ids { S_ID_REQUIRE = 1, S_ID_FC_TYPE = 2, S_ID_SEMICOLON = 3, S_ID_IF_CALLS_TEMPL = 4, S_ID_DECL_IN_IF = 5, S_ID_BARE_MODULE = 6, S_ID_MISSING_RANGE = 7, S_ID_UNQUOTE_GENREQ = 8, S_ID_PERM_SUFFIX = 9, S_ID_PERMMACRO = 10, S_END }; enum warn_ids { W_ID_NO_EXPLICIT_DECL = 1, W_ID_NO_REQ = 2, W_ID_UNUSED_REQ = 3, W_ID_FC_REGEX = 4, W_ID_IF_CALL_OPTIONAL = 5, W_ID_EMPTY_IF_CALL_ARG = 6, W_ID_SPACE_IF_CALL_ARG = 7, W_ID_RISKY_ALLOW_PERM = 8, W_ID_MOD_NAME_FILE = 9, W_ID_UNKNOWN_CALL = 10, W_ID_IF_DECL_NOT_OWN = 11, W_END }; enum error_ids { E_ID_FC_ERROR = 2, E_ID_FC_USER = 3, E_ID_FC_ROLE = 4, E_ID_FC_TYPE = 5, E_ID_DECL_IF_CLASH = 6, E_ID_UNKNOWN_PERM = 7, E_ID_UNKNOWN_CLASS = 8, E_ID_EMPTY_BLOCK = 9, E_ID_STRAY_WORD = 10, E_END }; enum fatal_ids { F_ID_POLICY_SYNTAX = 1, F_ID_INTERNAL = 2 }; enum file_flavor { FILE_TE_FILE, FILE_IF_FILE, FILE_FC_FILE }; struct check_data { char *mod_name; char *filename; enum file_flavor flavor; const struct config_check_data *config_check_data; }; // A check is responsible for filling out all fields except lineno // which is filled out by the calling function.` struct check_result { unsigned int lineno; char severity; unsigned int check_id; char *message; }; struct check_node { struct check_result *(*check_function) (const struct check_data * data, const struct policy_node * node); char *check_id; unsigned int issues_found; struct check_node *next; }; struct checks { struct check_node *check_nodes[NODE_ERROR + 1]; }; // Whether an issue was found extern int found_issue; // Whether found issues are printed individually extern int suppress_output; /********************************************* * Add an check to be called on check_flavor nodes * check_flavor - The flavor of node to call the check for * ck - The check structure to add the check to * check_id - The ID code for the check * check_function - the check to add * returns SELINT_SUCCESS or an error code on failure *********************************************/ enum selint_error add_check(enum node_flavor check_flavor, struct checks *ck, const char *check_id, struct check_result *(*check_function)(const struct check_data * check_data, const struct policy_node * node)); /********************************************* * Call all registered checks for node->flavor node types * and write any error messages to STDOUT * ck - The checks structure * data - Metadata about the file * node - the node to check * returns SELINT_SUCCESS or an error code on failure *********************************************/ enum selint_error call_checks(struct checks *ck, const struct check_data *data, const struct policy_node *node); /********************************************* * Helper function for call_checks that takes the appropriate * list of checks for the node flavor and writes any error messages to STDOUT * ck_list - The checks to run * data - Metadata about the file * node - the node to check * returns SELINT_SUCCESS or an error code on failure *********************************************/ enum selint_error call_checks_for_node_type(struct check_node *ck_list, const struct check_data *data, const struct policy_node *node); /********************************************* * Display a result message for a positive check finding * res - Information about the result of the check * data - Metadata about the file *********************************************/ void display_check_result(const struct check_result *res, const struct check_data *data); /********************************************* * Creates a check_result, using a printf style format string and optional * arguments to generate a message * severity - The severity of the check result * check_id - The check identifier * format - A printf style format string *********************************************/ __attribute__ ((format(printf, 3, 4))) struct check_result *make_check_result(char severity, unsigned int check_id, const char *format, ...); /********************************************* * Generates a check result for an internal error (F-002) * string - The error message to display *********************************************/ struct check_result *alloc_internal_error(const char *string); /********************************************* * Determine if a character represents a valid severity. * check_char - The character to check * returns true if it is a valid check and false otherwise *********************************************/ bool is_valid_severity(char check_char); /********************************************* * Determine if a string represents a valid check. * This compares vs all checks that are defined in the ids enums * check_str - The string to check * returns 1 if it is a valid check and 0 otherwise *********************************************/ int is_valid_check(const char *check_str); /********************************************* * Display a count of issues found in a run, but check ID. * Don't display checks with no issues found * ck - The checks structure, which should be already populated with issues_found * from an analysis run *********************************************/ void display_check_issue_counts(const struct checks *ck); void free_check_result(struct check_result *); void free_checks(struct checks *to_free); void free_check_node(struct check_node *to_free); #endif selint-1.2.1/src/ordering.c0000644000175100001710000007352414167117255012517 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define _GNU_SOURCE #include #include #include #include #include "ordering.h" #include "maps.h" #define SECTION_NON_ORDERED "_non_ordered" #define SECTION_DECLARATION "_declaration" static bool is_optional(const struct policy_node *node); static bool is_boolean(const struct policy_node *node); static bool is_tunable(const struct policy_node *node); static bool is_in_ifdef(const struct policy_node *node); // get next node, skip nodes marked with #selint-disable:C-001 static const struct policy_node *ordering_next(const struct policy_node *node) { const struct policy_node *next = node; do { next = dfs_next(next); } while (next && next->exceptions && strstr(next->exceptions, "C-001")); return next; } struct ordering_metadata *prepare_ordering_metadata(const struct check_data *data, const struct policy_node *head) { const struct policy_node *cur = head->next; // head is file. Order the contents size_t count = 0; struct section_data *sections = calloc(1, sizeof(struct section_data)); while (cur) { if (add_section_info(sections, get_section(cur), cur->lineno) == SELINT_BAD_ARG) { free(sections); return NULL; } count += 1; cur = ordering_next(cur); } calculate_average_lines(sections); struct ordering_metadata *ret = calloc(1, sizeof(struct ordering_metadata) + (count * sizeof(struct order_node))); ret->mod_name = data->mod_name; // Will only be needed for duration of check, so will remain allocated // until we are done with this copy ret->order_node_len = count; ret->sections = sections; // The nodes array will be populated during the LIS traversal return ret; } void calculate_longest_increasing_subsequence(const struct policy_node *head, struct ordering_metadata *ordering, enum order_difference_reason (*comp_func)(const struct ordering_metadata *o, const struct policy_node *first, const struct policy_node *second)) { struct order_node *nodes = ordering->nodes; int longest_seq = 0; int index = 0; const struct policy_node *cur = head->next; while (cur) { // Save the node in the array if (cur->flavor == NODE_START_BLOCK) { cur = ordering_next(cur); continue; } nodes[index].node = cur; // binary search sequences so far int low = 1; int high = longest_seq; while (low <= high) { int mid = (low + high + 1) / 2; // Ceiling if (comp_func(ordering, nodes[nodes[mid-1].end_of_seq].node, nodes[index].node) >= 0) { low = mid + 1; } else { high = mid - 1; } } // Now low should be 1 greater than the length of the longest // sequence that ends lower than the current number if (low <= 1) { nodes[index].seq_prev = -1; // No previous node } else { nodes[index].seq_prev = nodes[low - 2].end_of_seq; } nodes[low - 1].end_of_seq = index; if (low > longest_seq) { longest_seq = low; } index++; cur = ordering_next(cur); } // Mark LIS elements index = nodes[longest_seq - 1].end_of_seq; while (index != -1) { nodes[index].in_order = 1; index = nodes[index].seq_prev; } #ifdef DEBUG_INFO for (int i=0; i< ordering->order_node_len; i++) { if(nodes[i].node) { printf("Line: %u, Section %s: LSS: %d\n", nodes[i].node->lineno, get_section(nodes[i].node), get_local_subsection(ordering->mod_name, nodes[i].node)); } } #endif } enum selint_error add_section_info(struct section_data *sections, const char *section_name, unsigned int lineno) { if (sections == NULL || section_name == NULL) { return SELINT_BAD_ARG; } struct section_data *cur = sections; if (sections->section_name != NULL) { while (0 != strcmp(cur->section_name, section_name)) { if (cur->next == NULL) { cur->next = calloc(1, sizeof(struct section_data)); cur = cur->next; break; } cur = cur->next; } } // cur is now the appropriate section_data node. If section_name is // NULL, then this is a new node if (!cur->section_name) { cur->section_name = strdup(section_name); } cur->lineno_count++; cur->lines_sum += lineno; return SELINT_SUCCESS; } const char *get_section(const struct policy_node *node) { if (!node) { return NULL; //Error } switch (node->flavor) { case NODE_TE_FILE: case NODE_IF_FILE: case NODE_FC_FILE: case NODE_SPT_FILE: case NODE_AV_FILE: return NULL; // Should never happen case NODE_HEADER: return SECTION_NON_ORDERED; // Guaranteed at top by grammar case NODE_AV_RULE: case NODE_XAV_RULE: if (node->data.av_data->flavor == AV_RULE_NEVERALLOW) { // These are somewhat of a unique situation, and the style guide // doesn't mention them explicitly. Maybe they should just group // like other av rules, but they can often have multiple types. // Additionally, the below code assumes that the first string in // the sources is a type or attribute, but in the case of neverallows // it can be "~" return SECTION_NON_ORDERED; } if (node->data.av_data->flavor == AV_RULE_AUDITALLOW) { return SECTION_NON_ORDERED; } if (node->data.av_data->perms && (str_in_sl("associate", node->data.av_data->perms) || str_in_sl("mounton", node->data.av_data->perms))) { return SECTION_NON_ORDERED; // Can be transform or with rules } // The case of multiple source types is weird. For now // just using the first one seems fine. return node->data.av_data->sources->string; case NODE_TT_RULE: // TODO: Are type_member and type_change the same as tt // from an ordering standpoint? // The case of multiple source types is weird. For now // just using the first one seems fine. return node->data.av_data->sources->string; case NODE_RT_RULE: return SECTION_NON_ORDERED; case NODE_ROLE_ALLOW: case NODE_ROLE_TYPES: // These are not in the style guide. I normally see them grouped // with declarations, but maybe a future ordering configuration // can sort them that way return SECTION_NON_ORDERED; case NODE_DECL: case NODE_ALIAS: case NODE_TYPE_ALIAS: case NODE_TYPE_ATTRIBUTE: case NODE_ROLE_ATTRIBUTE: if (is_in_require(node)) { return SECTION_NON_ORDERED; } else { return SECTION_DECLARATION; } case NODE_M4_CALL: case NODE_M4_SIMPLE_MACRO: case NODE_DEFINE: return SECTION_NON_ORDERED; // TODO: It's probably way more complicated than this case NODE_OPTIONAL_POLICY: case NODE_OPTIONAL_ELSE: case NODE_BOOLEAN_POLICY: case NODE_TUNABLE_POLICY: case NODE_IFDEF: case NODE_IFELSE: return get_section(node->first_child); case NODE_M4_ARG: return SECTION_NON_ORDERED; //TODO case NODE_START_BLOCK: if (node->next) { return get_section(node->next); } else { return SECTION_NON_ORDERED; // empty block } case NODE_IF_CALL: // check for filetrans_if first to treat interfaces with the // flags filetrans and transform as _non-ordered if (is_filetrans_if(node->data.ic_data->name)) { return SECTION_NON_ORDERED; } else if (!is_optional(node) && !is_in_ifdef(node) && !is_boolean(node) && !is_tunable(node) && (look_up_in_template_map(node->data.ic_data->name) || is_transform_if(node->data.ic_data->name) || is_role_if(node->data.ic_data->name))) { return SECTION_DECLARATION; } else { if (node->data.ic_data->args) { return node->data.ic_data->args->string; } else { // Empty interface call return SECTION_NON_ORDERED; } } case NODE_TEMP_DEF: case NODE_INTERFACE_DEF: return NULL; // if files only case NODE_REQUIRE: case NODE_GEN_REQ: return SECTION_NON_ORDERED; // Not in style guide case NODE_PERMISSIVE: return SECTION_NON_ORDERED; // Not in style guide case NODE_FC_ENTRY: return NULL; // fc files only case NODE_COMMENT: case NODE_EMPTY: case NODE_SEMICOLON: case NODE_ERROR: return SECTION_NON_ORDERED; default: // Should never happen return NULL; } } void calculate_average_lines(struct section_data *sections) { while (sections) { sections->avg_line = (float)sections->lines_sum / (float)sections->lineno_count; sections = sections->next; } } float get_avg_line_by_name(const char *section_name, const struct section_data *sections) { while (0 != strcmp(sections->section_name, section_name)) { sections = sections->next; if (!sections) { return -1; //Error } } return sections->avg_line; } static bool is_self_rule(const struct policy_node *node) { return (node->flavor == NODE_AV_RULE || node->flavor == NODE_XAV_RULE) && node->data.av_data && node->data.av_data->targets && 0 == strcmp(node->data.av_data->targets->string, "self"); } static bool is_own_module_rule(const struct policy_node *node, const char *current_mod_name) { if (node->flavor != NODE_AV_RULE && node->flavor != NODE_XAV_RULE && node->flavor != NODE_IF_CALL) { return false; } if (node->flavor == NODE_IF_CALL) { // These should actually be patterns, not real calls if (look_up_in_ifs_map(node->data.ic_data->name)) { return false; } } struct string_list *names = get_names_in_node(node); struct string_list *cur = names; while (cur) { const char *module_of_type_or_attr = look_up_in_decl_map(cur->string, DECL_TYPE); if (!module_of_type_or_attr) { module_of_type_or_attr = look_up_in_decl_map(cur->string, DECL_ATTRIBUTE); } if (module_of_type_or_attr && 0 != strcmp(module_of_type_or_attr, current_mod_name)) { free_string_list(names); return false; } cur = cur->next; } free_string_list(names); // This assumes that not found strings are not types from other modules. // This is probably necessary because we'll find strings like "file" or // "read_file_perms" for example. However, in normal mode without context // this could definitely be a problem because we won't find types from // other modules return true; } static bool is_kernel_mod_if_call(const struct policy_node *node) { if (node->flavor != NODE_IF_CALL) { return false; } const char *mod_name = look_up_in_ifs_map(node->data.ic_data->name); if (!mod_name) { return false; } if (0 == strcmp("kernel", mod_name)) { return true; } return false; } static bool is_own_mod_if_call(const struct policy_node *node, const char *current_mod_name) { if (node->flavor != NODE_IF_CALL) { return false; } const char *mod_name = look_up_in_ifs_map(node->data.ic_data->name); if (!mod_name) { return false; } if (current_mod_name && 0 != strcmp(current_mod_name, mod_name)) { return false; } return true; } static bool is_related_mod_if_call(const struct policy_node *node, const char *current_mod_name) { if (node->flavor != NODE_IF_CALL) { return false; } const char *current_mod_prefix = strchr(current_mod_name, '_'); size_t cur_prefix_len; if (current_mod_prefix) { cur_prefix_len = (size_t)(current_mod_prefix - current_mod_name); } else { cur_prefix_len = strlen(current_mod_name); } const char *mod_name = look_up_in_ifs_map(node->data.ic_data->name); if (!mod_name) { return false; } const char *mod_prefix = strchr(mod_name, '_'); size_t prefix_len; if (mod_prefix) { prefix_len = (size_t)(mod_prefix - mod_name); } else { prefix_len = strlen(mod_name); } if (cur_prefix_len == prefix_len && 0 == strncmp(current_mod_name, mod_name, cur_prefix_len)) { return true; } return false; } static bool check_call_layer(const struct policy_node *node, const char *layer_to_check) { if (node->flavor != NODE_IF_CALL) { return false; } const char *mod_name = look_up_in_ifs_map(node->data.ic_data->name); if (!mod_name) { // not an actual interface return false; } const char *layer_name = look_up_in_mod_layers_map(mod_name); if (!layer_name) { return false; } return (0 == strcmp(layer_name, layer_to_check)); } static bool is_kernel_layer_if_call(const struct policy_node *node) { return check_call_layer(node, "kernel"); } static bool is_system_layer_if_call(const struct policy_node *node) { return check_call_layer(node, "system"); } static bool is_optional(const struct policy_node *node) { bool ret = false; while (node) { if (node->flavor == NODE_OPTIONAL_POLICY || node->flavor == NODE_OPTIONAL_ELSE) { ret = true; } else if (node->flavor == NODE_BOOLEAN_POLICY || node->flavor == NODE_TUNABLE_POLICY || node->flavor == NODE_IFDEF || node->flavor == NODE_IFELSE) { ret = false; } node = node->parent; } return ret; } static bool is_boolean(const struct policy_node *node) { bool ret = false; while (node) { if (node->flavor == NODE_BOOLEAN_POLICY) { ret = true; } else if (node->flavor == NODE_TUNABLE_POLICY || node->flavor == NODE_OPTIONAL_POLICY || node->flavor == NODE_OPTIONAL_ELSE || node->flavor == NODE_IFDEF || node->flavor == NODE_IFELSE) { ret = false; } node = node->parent; } return ret; } static bool is_tunable(const struct policy_node *node) { bool ret = false; while (node) { if (node->flavor == NODE_TUNABLE_POLICY) { ret = true; } else if (node->flavor == NODE_BOOLEAN_POLICY || node->flavor == NODE_OPTIONAL_POLICY || node->flavor == NODE_OPTIONAL_ELSE || node->flavor == NODE_IFDEF || node->flavor == NODE_IFELSE) { ret = false; } node = node->parent; } return ret; } static bool is_in_ifdef(const struct policy_node *node) { bool ret = false; while (node) { if (node->flavor == NODE_IFDEF || node->flavor == NODE_IFELSE) { ret = true; } else if (node->flavor == NODE_OPTIONAL_POLICY || node->flavor == NODE_OPTIONAL_ELSE || node->flavor == NODE_BOOLEAN_POLICY || node->flavor == NODE_TUNABLE_POLICY) { ret = false; } node = node->parent; } return ret; } enum local_subsection get_local_subsection(const char *mod_name, const struct policy_node *node, enum order_conf variant) { if (!node) { return LSS_UNKNOWN; } if (is_in_ifdef(node)) { return LSS_BUILD_OPTION; } else if (is_optional(node)) { return LSS_OPTIONAL; } else if (is_boolean(node)) { return LSS_BOOLEAN; } else if (is_tunable(node)) { return LSS_TUNABLE; } else if (is_self_rule(node)) { return LSS_SELF; } else if (is_own_module_rule(node, mod_name)) { return LSS_OWN; } else if (is_own_mod_if_call(node, mod_name)) { return LSS_OWN; } else if (variant != ORDER_REF && is_related_mod_if_call(node, mod_name)) { return LSS_RELATED; } else if (is_kernel_mod_if_call(node)) { return LSS_KERNEL_MOD; } else if (variant != ORDER_LIGHT && is_kernel_layer_if_call(node)) { return LSS_KERNEL; } else if (variant != ORDER_LIGHT && is_system_layer_if_call(node)) { return LSS_SYSTEM; } else if (node->flavor == NODE_IF_CALL) { return LSS_OTHER; } else { // TODO conditional, optional etc return LSS_UNKNOWN; } } /* * Treat the following as the same section: * foo_t and foo_r * foo and foo_t * foo and foo_r */ static bool is_same_section(const char *first_section_name, const char *second_section_name) { size_t first_length = strlen(first_section_name); size_t second_length = strlen(second_section_name); if (first_length >= 3 && (first_section_name[first_length-1] == 't' || first_section_name[first_length-1] == 'r') && first_section_name[first_length-2] == '_') { first_length -= 2; } if (second_length >= 3 && (second_section_name[second_length-1] == 't' || second_section_name[second_length-1] == 'r') && second_section_name[second_length-2] == '_') { second_length -= 2; } return (0 == strncmp(first_section_name, second_section_name, first_length > second_length ? first_length : second_length)); } #define CHECK_ORDERING(to_check_first, to_check_second, comp, ret) \ if (to_check_first == comp) { \ return ret; \ } \ if (to_check_second == comp) { \ return -ret; \ } \ // Call this in order of an ordering on enums. It returns a positive or // negative value based on which one it encounters first. #define CHECK_FLAVOR_ORDERING(data_flavor, comp, ret) \ CHECK_ORDERING(first->data.data_flavor->flavor, second->data.data_flavor->flavor, comp, ret) enum order_difference_reason compare_nodes_refpolicy_generic(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second, enum order_conf variant) { const char *first_section_name = get_section(first); const char *second_section_name = get_section(second); if (first_section_name == NULL || second_section_name == NULL) { return ORDERING_ERROR; } if (0 == strcmp(first_section_name, SECTION_NON_ORDERED) || 0 == strcmp(second_section_name, SECTION_NON_ORDERED)) { return ORDER_EQUAL; } if (!is_same_section(first_section_name, second_section_name)) { if (0 != strcmp(first_section_name, SECTION_DECLARATION) && (0 == strcmp(second_section_name, SECTION_DECLARATION) || (get_avg_line_by_name(first_section_name, ordering_data->sections) > get_avg_line_by_name(second_section_name, ordering_data->sections))) && // allow raw section alphabetically following another raw section (!(first_section_name[0] != '_' && second_section_name[0] != '_' && strcmp(first_section_name, second_section_name) < 0))) { return -ORDER_SECTION; } else { return ORDER_SECTION; } } // If we made it to this point the two nodes are in the same section if (0 == strcmp(first_section_name, SECTION_DECLARATION)) { if (first->flavor == NODE_DECL && second->flavor == NODE_DECL) { if (first->data.d_data->flavor != second->data.d_data->flavor) { CHECK_FLAVOR_ORDERING(d_data, DECL_BOOL, ORDER_DECLARATION_SUBSECTION); CHECK_FLAVOR_ORDERING(d_data, DECL_ATTRIBUTE, ORDER_DECLARATION_SUBSECTION); // Types and roles should intersperse } else { // TODO: same subsection } } return ORDER_EQUAL; } // Local policy rules sections const enum local_subsection lss_first = get_local_subsection(ordering_data->mod_name, first, variant); const enum local_subsection lss_second = get_local_subsection(ordering_data->mod_name, second, variant); if (lss_first == LSS_UNKNOWN || lss_second == LSS_UNKNOWN) { return ORDER_EQUAL; // ... Maybe? Should this case be handled earlier? } if (lss_first != lss_second) { CHECK_ORDERING(lss_first, lss_second, LSS_SELF, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_OWN, ORDER_LOCAL_SUBSECTION); if (variant == ORDER_REF) { CHECK_ORDERING(lss_first, lss_second, LSS_KERNEL_MOD, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_KERNEL, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_SYSTEM, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_OTHER, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_BUILD_OPTION, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_BOOLEAN, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_TUNABLE, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_OPTIONAL, ORDER_LOCAL_SUBSECTION); } else if (variant == ORDER_LIGHT) { CHECK_ORDERING(lss_first, lss_second, LSS_RELATED, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_KERNEL_MOD, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_OTHER, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_BUILD_OPTION, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_BOOLEAN, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_TUNABLE, ORDER_LOCAL_SUBSECTION); CHECK_ORDERING(lss_first, lss_second, LSS_OPTIONAL, ORDER_LOCAL_SUBSECTION); } } if (variant == ORDER_REF || variant == ORDER_LIGHT) { // alphabetical top-level interfaces if (lss_first != LSS_BUILD_OPTION && lss_first != LSS_BOOLEAN && lss_first != LSS_TUNABLE && (lss_first != LSS_OPTIONAL || // sort optionals only based on first node (lss_first == lss_second && first->prev->flavor == NODE_START_BLOCK && second->prev->flavor == NODE_START_BLOCK)) && first->flavor == NODE_IF_CALL && second->flavor == NODE_IF_CALL) { const char *first_mod_name = look_up_in_ifs_map(first->data.ic_data->name); const char *second_mod_name = look_up_in_ifs_map(second->data.ic_data->name); if (first_mod_name && second_mod_name) { const int compare = strcmp(first_mod_name, second_mod_name); if (compare < 0) { return ORDER_ALPHABETICAL; } else if (compare > 0) { return -ORDER_ALPHABETICAL; } } } // alphabetical optionals // sort by the first node in a optional block if (lss_first == LSS_OPTIONAL && lss_second == LSS_OPTIONAL && first->first_child && first->first_child->next && second->first_child && second->first_child->next) { return compare_nodes_refpolicy_generic(ordering_data, first->first_child->next, second->first_child->next, variant); } } return ORDER_EQUAL; } enum order_difference_reason compare_nodes_refpolicy(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second) { return compare_nodes_refpolicy_generic(ordering_data, first, second, ORDER_REF); } enum order_difference_reason compare_nodes_refpolicy_light(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second) { return compare_nodes_refpolicy_generic(ordering_data, first, second, ORDER_LIGHT); } enum order_difference_reason compare_nodes_refpolicy_lax(const struct ordering_metadata *ordering_data, const struct policy_node *first, const struct policy_node *second) { return compare_nodes_refpolicy_generic(ordering_data, first, second, ORDER_LAX); } const char *lss_to_string(enum local_subsection lss) { switch (lss) { case LSS_SELF: return "self rule"; case LSS_OWN: return "own module rule"; case LSS_RELATED: return "related module interface"; case LSS_KERNEL_MOD: return "kernel module interface"; case LSS_KERNEL: return "kernel layer interface"; case LSS_SYSTEM: return "system layer interface"; case LSS_OTHER: return "general interface"; case LSS_BUILD_OPTION: return "build option"; case LSS_BOOLEAN: return "boolean policy block"; case LSS_TUNABLE: return "tunable policy block"; case LSS_OPTIONAL: return "optional policy block"; case LSS_UNKNOWN: default: return "unknown subsection"; } } char *get_ordering_reason(struct ordering_metadata *order_data, unsigned int index, enum order_conf variant) { unsigned int distance = 1; unsigned int nearest_index = 0; enum order_difference_reason reason = ORDER_EQUAL; while (nearest_index == 0) { if (distance < index && order_data->nodes[index-distance].in_order) { reason = compare_nodes_refpolicy_generic(order_data, order_data->nodes[index-distance].node, order_data->nodes[index].node, variant); if (reason < 0) { nearest_index = index - distance; break; } } if (index + distance < order_data->order_node_len && order_data->nodes[index+distance].in_order) { reason = compare_nodes_refpolicy_generic(order_data, order_data->nodes[index].node, order_data->nodes[index+distance].node, variant); if (reason < 0) { nearest_index = index + distance; break; } } distance++; if ((distance > index) && (index + distance > order_data->order_node_len)) { return NULL; // Error } } const struct policy_node *this_node = order_data->nodes[index].node; const struct policy_node *other_node = order_data->nodes[nearest_index].node; const char *before_after; if (nearest_index > index) { before_after = "before"; } else { before_after = "after"; } const char *reason_str; char *followup_str = NULL; enum local_subsection other_lss; const char *node_section; const char *other_section; switch (-reason) { case ORDER_EQUAL: return NULL; // Error case ORDER_SECTION: node_section = get_section(this_node); other_section = get_section(other_node); if (!node_section || !other_section) { return NULL; // Error } if (0 == strcmp(SECTION_DECLARATION, node_section)) { // This is the first section reason_str = "that is not a declaration"; } else if (0 == strcmp(SECTION_DECLARATION, other_section)) { // The other section is the first section if (other_node->flavor == NODE_IF_CALL && is_transform_if(other_node->data.ic_data->name)) { reason_str = "that is a transform interface"; } else { reason_str = "that is a declaration"; } } else { reason_str = "that is in a different section"; } int r = asprintf(&followup_str, " (This node is in the section for %s rules and the other is in the section for %s rules.)", node_section, other_section); if (r == -1) { return NULL; //ERROR } break; case ORDER_DECLARATION_SUBSECTION: reason_str = "that is associated with a different sort of declaration"; break; case ORDER_LOCAL_SUBSECTION: other_lss = get_local_subsection(order_data->mod_name, other_node, variant); switch (other_lss) { case LSS_SELF: reason_str = "that is a self rule"; break; case LSS_OWN: reason_str = "that refers to types owned by this module"; break; case LSS_RELATED: reason_str = "that calls an interface located in a related module"; break; case LSS_KERNEL_MOD: reason_str = "that calls an interface located in the kernel module"; break; case LSS_KERNEL: reason_str = "that calls an interface located in the kernel layer"; break; case LSS_SYSTEM: reason_str = "that calls an interface located in the system layer"; break; case LSS_OTHER: reason_str = variant == ORDER_REF ? "that calls an interface not located in the kernel or system layer" : "that calls a non-optional interface"; break; case LSS_BUILD_OPTION: reason_str = "that is controlled by a build option"; break; case LSS_BOOLEAN: reason_str = "that is in a boolean block"; break; case LSS_TUNABLE: reason_str = "that is in a tunable block"; break; case LSS_OPTIONAL: reason_str = "that is in an optional block"; break; case LSS_UNKNOWN: return NULL; //Error default: //Shouldn't happen return NULL; } if (other_lss == LSS_KERNEL || other_lss == LSS_SYSTEM || other_lss == LSS_OTHER) { enum local_subsection this_lss = get_local_subsection(order_data->mod_name, this_node, variant); if (this_lss == LSS_KERNEL) { followup_str = strdup(" (This interface is in the kernel layer.)"); } else if (this_lss == LSS_SYSTEM) { followup_str = strdup(" (This interface is in the system layer.)"); } else if (this_lss == LSS_OTHER) { followup_str = strdup(" (This interface is in a layer other than kernel or system.)"); } else if (this_lss == LSS_KERNEL_MOD) { followup_str = strdup(" (This interface is in the kernel module.)"); } // Otherwise, it's not an interface call and is hopefully obvious to the user what layer its in } break; case ORDER_ALPHABETICAL: if (nearest_index > index) { reason_str = "that is alphabetically earlier"; } else { reason_str = "that is alphabetically later"; } break; case ORDERING_ERROR: return NULL; default: //Shouldn't happen return NULL; } size_t str_len = strlen(reason_str) + strlen(before_after) + strlen("Line out of order. It is of type ") + strlen(lss_to_string(get_local_subsection(order_data->mod_name, this_node, variant))) + 1 + strlen(" line ") + 13; // 13 is enough for the maximum // length of an unsigned int (10) // plus a final period, a space // and a null terminator if (followup_str) { str_len += strlen(followup_str); } char *ret = malloc(sizeof(char) * str_len); ssize_t written = snprintf(ret, str_len, "Line out of order. It is of type %s %s line %u %s.", lss_to_string(get_local_subsection(order_data->mod_name, this_node, variant)), before_after, other_node->lineno, reason_str); if (written < 0) { free(followup_str); free(ret); return NULL; } if (followup_str) { strncat(ret, followup_str, str_len - (size_t)written); } free(followup_str); return ret; } void free_ordering_metadata(struct ordering_metadata *to_free) { if (to_free == NULL) { return; } free_section_data(to_free->sections); free(to_free); } void free_section_data(struct section_data *to_free) { if (to_free == NULL) { return; } free(to_free->section_name); free_section_data(to_free->next); free(to_free); } selint-1.2.1/src/startup.c0000644000175100001710000001367714167117255012413 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "startup.h" #include "color.h" #include "maps.h" #include "parse.h" #include "parse_functions.h" #include "tree.h" #include "util.h" #include "parse.h" enum selint_error load_access_vectors_kernel(const char *av_path) { /* check if av_path really exists, * e.g. checking nonexistent /sys/fs/selinux/class * on a SELinux disabled system */ if (access(av_path, F_OK) != 0) { return SELINT_IO_ERROR; } enum selint_error r = SELINT_PARSE_ERROR; const char *paths[2] = { av_path, NULL }; IGNORE_CONST_DISCARD_BEGIN; FTS *ftsp = fts_open(paths, FTS_PHYSICAL, NULL); IGNORE_CONST_DISCARD_END; FTSENT *file = fts_read(ftsp); while (file) { if (file->fts_level != 0 && file->fts_info == FTS_D && 0 != strcmp(file->fts_name, "perms")) { // Directory being visited the first time insert_into_decl_map(file->fts_name, "class", DECL_CLASS); } else if (file->fts_info == FTS_F && 0 != strcmp(file->fts_name, "index")) { // File insert_into_decl_map(file->fts_name, "perm", DECL_PERM); r = SELINT_SUCCESS; } file = fts_read(ftsp); } fts_close(ftsp); return r; } enum selint_error load_access_vectors_source(const char *av_path) { print_if_verbose("Parsing access_vector file %s\n", av_path); set_current_module_name(av_path); FILE *f = fopen(av_path, "r"); if (!f) { printf("%sError%s: Failed to open %s: %s\n", color_error(), color_reset(), av_path, strerror(errno)); return SELINT_IO_ERROR; } struct policy_node *ast = yyparse_wrapper(f, av_path, NODE_AV_FILE); fclose(f); if (!ast) { return SELINT_PARSE_ERROR; } free_policy_node(ast); return SELINT_SUCCESS; } void load_modules_normal() { } static int is_space(char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r'; } static char *strip_space(char *str) { while (is_space(*str)) { str++; } char *end = str; while (!is_space(*end)) { end++; } *end = '\0'; return str; } enum selint_error load_modules_source(const char *modules_conf_path) { FILE *fd = fopen(modules_conf_path, "r"); if (!fd) { return SELINT_IO_ERROR; } char *line = NULL; ssize_t len_read = 0; size_t buf_len = 0; while ((len_read = getline(&line, &buf_len, fd)) != -1) { if (len_read <= 1 || line[0] == '#') { continue; } char *pos = line; while (*pos != '\0' && is_space(*pos)) { pos++; } if (pos[0] == '#' || pos[0] == '\0') { continue; } pos = strtok(line, "="); if (!pos) { free(line); fclose(fd); return SELINT_PARSE_ERROR; } char *mod_name = strip_space(pos); pos = strtok(NULL, "="); if (!pos) { free(line); fclose(fd); return SELINT_PARSE_ERROR; } char *status = strip_space(pos); insert_into_mods_map(mod_name, status); if (strtok(NULL, "=")) { free(line); fclose(fd); return SELINT_PARSE_ERROR; } } free(line); fclose(fd); return SELINT_SUCCESS; } enum selint_error load_obj_perm_sets_source(const char *obj_perm_sets_path) { FILE *f = fopen(obj_perm_sets_path, "r"); if (!f) { return SELINT_IO_ERROR; } struct policy_node *ast = yyparse_wrapper(f, obj_perm_sets_path, NODE_SPT_FILE); fclose(f); if (ast == NULL) { return SELINT_PARSE_ERROR; } free_policy_node(ast); return SELINT_SUCCESS; } static int mark_transform_interfaces_one_file(const struct policy_node *ast) { int marked_transform = 0; const struct policy_node *cur = ast; while (cur) { if (cur->flavor == NODE_INTERFACE_DEF && cur->first_child && !is_transform_if(cur->data.str)) { const struct policy_node *child = cur->first_child; while (child && (child->flavor == NODE_START_BLOCK || child->flavor == NODE_REQUIRE || child->flavor == NODE_GEN_REQ)) { child = child->next; } if (!child) { // Nothing in interface besides possibly require cur = dfs_next(cur); continue; } if (child->flavor == NODE_IF_CALL) { if (is_transform_if(child->data.ic_data->name)) { mark_transform_if(cur->data.str); marked_transform = 1; } } } cur = dfs_next(cur); } return marked_transform; } enum selint_error load_devel_headers(struct policy_file_list *context_files) { const char *header_loc = "/usr/share/selinux/devel"; const char *paths[2] = {header_loc, 0}; IGNORE_CONST_DISCARD_BEGIN; FTS *ftsp = fts_open(paths, FTS_PHYSICAL | FTS_NOSTAT, NULL); IGNORE_CONST_DISCARD_END; FTSENT *file = fts_read(ftsp); while (file) { const char *suffix = (file->fts_pathlen > 3) ? (file->fts_path + file->fts_pathlen - 3) : NULL; if (suffix && !strcmp(suffix, ".if")) { file_list_push_back(context_files, make_policy_file(file->fts_path, NULL)); char *mod_name = strdup(file->fts_name); mod_name[file->fts_namelen - 3] = '\0'; insert_into_mod_layers_map(mod_name, file->fts_parent->fts_name); free(mod_name); } file = fts_read(ftsp); } fts_close(ftsp); return SELINT_SUCCESS; } enum selint_error mark_transform_interfaces(const struct policy_file_list *files) { const struct policy_file_node *cur; int marked_transform; do { marked_transform = 0; cur = files->head; while (cur) { marked_transform = marked_transform || mark_transform_interfaces_one_file(cur->file->ast); cur = cur->next; } } while (marked_transform); return SELINT_SUCCESS; } selint-1.2.1/src/te_checks.c0000644000175100001710000006211214167117255012625 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "color.h" #include "te_checks.h" #include "maps.h" #include "tree.h" #include "ordering.h" #include "util.h" #include "perm_macro.h" struct check_result *check_te_order(const struct check_data *data, const struct policy_node *node) { if (!data || !data->config_check_data) { return alloc_internal_error("Uninitialized data given to C-001"); } if (data->flavor != FILE_TE_FILE) { return NULL; } static struct ordering_metadata *order_data; static unsigned int order_node_arr_index; switch (node->flavor) { case NODE_TE_FILE: order_data = prepare_ordering_metadata(data, node); order_node_arr_index = 0; if (!order_data) { return alloc_internal_error("Failed to initialize ordering for C-001"); } switch (data->config_check_data->order_conf) { case ORDER_REF: calculate_longest_increasing_subsequence(node, order_data, compare_nodes_refpolicy); break; case ORDER_LIGHT: calculate_longest_increasing_subsequence(node, order_data, compare_nodes_refpolicy_light); break; case ORDER_LAX: calculate_longest_increasing_subsequence(node, order_data, compare_nodes_refpolicy_lax); break; default: return alloc_internal_error("Unknown ordering configuration given to C-001"); } break; case NODE_CLEANUP: free_ordering_metadata(order_data); order_data = NULL; break; default: if (!order_data) { return alloc_internal_error("Ordering data was not generated for C-001"); } for (unsigned int i=order_node_arr_index; i < order_data->order_node_len; i++) { if (order_data->nodes[i].node == node) { order_node_arr_index = i; if (order_data->nodes[i].in_order) { return NULL; } else { char *reason_str = get_ordering_reason(order_data, order_node_arr_index, data->config_check_data->order_conf); if (!reason_str) { return alloc_internal_error("Failed to compute reason C-001"); } struct check_result *to_ret = make_check_result('C', C_ID_TE_ORDER, "%s", reason_str); free(reason_str); return to_ret; } } } return alloc_internal_error("Could not find ordering info for line"); } return NULL; } struct check_result *check_unordered_perms(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { const struct string_list *prev = NULL, *cur = NULL; const char *flavor; if (node->flavor == NODE_AV_RULE) { cur = node->data.av_data->perms; flavor = "av rule"; } else if (node->flavor == NODE_XAV_RULE) { cur = node->data.xav_data->perms; flavor = "xav rule"; } else if (node->flavor == NODE_DECL) { // ignore non-class declarations if (node->data.d_data->flavor != DECL_CLASS) { return NULL; } cur = node->data.d_data->attrs; flavor = "class declaration"; } else { return alloc_internal_error("Invalid node type for `check_unordered_perms`"); } while (cur) { if (prev && strcmp(prev->string, "~") != 0 && strcmp(cur->string, "-") != 0) { const int compare = strcmp(prev->string, cur->string); if (compare > 0) { return make_check_result('C', C_ID_UNORDERED_PERM, "Permissions in %s not ordered (%s before %s)", flavor, prev->string, cur->string); } else if (compare == 0) { return make_check_result('C', C_ID_UNORDERED_PERM, "Permissions in %s repeated (%s)", flavor, cur->string); } } prev = cur; cur = cur->next; } return NULL; } struct check_result *check_no_self(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { if (node->flavor != NODE_AV_RULE && node->flavor != NODE_XAV_RULE) { return alloc_internal_error("Bad node type given to check C-007"); } struct av_rule_data *av_data = node->data.av_data; if (av_data->sources->next || av_data->targets->next || 0 == strcmp(av_data->targets->string, "self") || 0 != strcmp(av_data->sources->string, av_data->targets->string)) { return NULL; } if (av_data->sources->string[0] == '$') { // On variables, we skip unless they are "_t" suffixed if (!ends_with(av_data->sources->string, strlen(av_data->sources->string), "_t", 2)) { return NULL; } } else if (!look_up_in_decl_map(av_data->sources->string, DECL_TYPE)) { // skip attributes return NULL; } return make_check_result('C', C_ID_SELF, "Recommend use of self keyword instead of redundant type"); } struct check_result *check_require_block(const struct check_data *data, const struct policy_node *node) { if (data->flavor != FILE_TE_FILE) { return NULL; } struct policy_node *cur = node->first_child; while (cur) { if (cur->flavor != NODE_DECL) { cur = cur->next; continue; } if (cur->data.d_data->flavor != DECL_CLASS && cur->data.d_data->flavor != DECL_PERM) { return make_check_result('S', S_ID_REQUIRE, "Require block used in te file (use an interface call instead)"); } cur = cur->next; } // Require contained only object classes and permissions return NULL; } struct check_result *check_useless_semicolon(__attribute__((unused)) const struct check_data *data, __attribute__((unused)) const struct policy_node *node) { return make_check_result('S', S_ID_SEMICOLON, "Unnecessary semicolon"); } struct check_result *check_bare_module_statement(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { if (node->data.h_data->flavor == HEADER_BARE) { return make_check_result('S', S_ID_BARE_MODULE, "Bare module statement (use `policy_module()` instead)"); } return NULL; } // check if all classes are netlink socket classes static bool all_netlink_socket_classes(const struct string_list *classes) { for (; classes; classes = classes->next) { if (0 != strncmp(classes->string, "netlink_", strlen("netlink_"))) { return false; } } return true; } // check if all classes are socket classes static bool all_socket_classes(const struct string_list *classes) { for (; classes; classes = classes->next) { if (!ends_with(classes->string, strlen(classes->string), "_socket", strlen("_socket"))) { return false; } } return true; } // check if '$STR' ends with '$SUFFIX_perms' static bool ends_with_suffix_perms(const char *str, size_t str_len, const char *suffix, size_t suffix_len) { if (str_len < (suffix_len + strlen("_perms"))) { return 0; } // no need to check last 6 characters are actual '_perms' // we call this only on strings we have checked to have this suffix return (0 == strncmp(str + str_len - (suffix_len + strlen("_perms")), suffix, suffix_len)); } static bool ends_with_all_suffix_perms(const char *str, size_t str_len, const struct string_list *classes) { for (; classes; classes = classes->next) { if (!ends_with_suffix_perms(str, str_len, classes->string, strlen(classes->string))) { // check class alias as fallback static const char *const class_aliases[][2] = { { "chr_file", "term" }, { "process", "signal" }, }; const char *class_alias = NULL; for (size_t i = 0; i < (sizeof class_aliases / sizeof *class_aliases); ++i) { if (0 == strcmp(classes->string, class_aliases[i][0])) { class_alias = class_aliases[i][1]; break; } } if (!class_alias || !ends_with_suffix_perms(str, str_len, class_alias, strlen(class_alias))) { return false; } } } return true; } struct check_result *check_perm_macro_class_mismatch(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { static const char *const file_suffix_classes[] = { "lnk_file", "chr_file", "blk_file", "sock_file", "fifo_file", }; const struct string_list *classes = node->data.av_data->object_classes; // ignore class set av rules if (ends_with(classes->string, strlen(classes->string), "_class_set", strlen("_class_set"))) { return NULL; } const bool is_file_class = str_in_sl("file", classes); const bool is_netlink_socket_class = all_netlink_socket_classes(classes); const bool is_socket_class = all_socket_classes(classes); for (const struct string_list *perms = node->data.av_data->perms; perms; perms = perms->next) { const size_t perm_len = strlen(perms->string); // ignore permissions without '_perms' suffix; they are probably not macros if (!ends_with(perms->string, perm_len, "_perms", strlen("_perms"))) { continue; } // ignore permissions matching 'something[_something]_$CLASSNAME_perms' // and 'something[_something]_$CLASSNAMEALIAS_perms' if (ends_with_all_suffix_perms(perms->string, perm_len, classes)) { // report usage of macros matching different class with actual class as suffix // e.g. report 'something_fifo_file_perms' for class 'file' if (is_file_class) { for (size_t i = 0; i < (sizeof file_suffix_classes / sizeof *file_suffix_classes); ++i) { if (ends_with_suffix_perms(perms->string, perm_len, file_suffix_classes[i], strlen(file_suffix_classes[i]))) { goto report; } } } continue; } // ignore permissions 'something[_something]_netlink_socket_perms' for netlink classes if (is_netlink_socket_class && ends_with(perms->string, perm_len, "_socket_perms", strlen("_socket_perms"))) { continue; } // ignore permissions 'something[_something]_socket_perms' for (non-netlink) socket classes if (is_socket_class && !is_netlink_socket_class && ends_with(perms->string, perm_len, "_socket_perms", strlen("_socket_perms")) && !ends_with(perms->string, perm_len, "netlink_socket_perms", strlen("netlink_socket_perms"))) { continue; } report: return make_check_result('S', S_ID_PERM_SUFFIX, "Permission macro %s does not match class %s", perms->string, classes->next ? "(multi class av rule)" : classes->string); } return NULL; } struct check_result *check_perm_macro_available(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { // ignore non allow rules if (node->data.av_data->flavor != AV_RULE_ALLOW) { return NULL; } // ignore multi class av rules const struct string_list *class = node->data.av_data->object_classes; if (class->next || ends_with(class->string, strlen(class->string), "_class_set", strlen("_class_set"))) { return NULL; } char *check_str = permmacro_check(node->data.av_data->object_classes->string, node->data.av_data->perms); if (!check_str) { return NULL; } struct check_result *res = make_check_result('S', S_ID_PERMMACRO, "%s", check_str); free(check_str); return res; } // Helper for check_no_explicit_declaration. Returns 1 is there is a require block // for name earlier in the file, and 0 otherwise static int has_require(const struct policy_node *node, const char *name, enum decl_flavor flavor) { const struct policy_node *cur = node; while (cur) { if (cur->flavor == NODE_REQUIRE || cur->flavor == NODE_GEN_REQ) { cur = cur->first_child; while (1) { if (cur->flavor == NODE_DECL && cur->data.d_data->flavor == flavor) { if (0 == strcmp(name, cur->data.d_data->name)) { return 1; } struct string_list *other_types = cur->data.d_data->attrs; // In requires these // are types, not // attributes while (other_types) { if (0 == strcmp(name, other_types->string)) { return 1; } other_types = other_types->next; } } if (cur->next) { cur = cur->next; } else { break; } } // Not found in this require block, keep going cur = cur->parent; if (!cur) { break; } } if (cur->prev) { cur = cur->prev; } else { cur = cur->parent; } } return 0; } struct check_result *check_no_explicit_declaration(const struct check_data *data, const struct policy_node *node) { if (data->flavor != FILE_TE_FILE) { return NULL; } struct string_list *names = get_names_in_node(node); const struct string_list *name = names; /* In declarations skip the first name, which is the new declared type */ if (node->flavor == NODE_DECL) { name = name->next; } for (; name; name = name->next) { const char *mod_name; enum decl_flavor flavor; if ((mod_name = look_up_in_decl_map(name->string, DECL_TYPE))) { flavor = DECL_TYPE; } else if ((mod_name = look_up_in_decl_map(name->string, DECL_ATTRIBUTE))) { flavor = DECL_ATTRIBUTE; } else if ((mod_name = look_up_in_decl_map(name->string, DECL_ATTRIBUTE_ROLE))) { flavor = DECL_ATTRIBUTE_ROLE; // Do not check for roles: in refpolicy they are defined in the kernel module // and used in role modules (like unprivuser) } else { //Not a known name continue; } if (0 != strcmp(data->mod_name, mod_name)) { // It may be required if (!has_require(node, name->string, flavor)) { // We didn't find a require block with this name struct check_result *to_ret = make_check_result('W', W_ID_NO_EXPLICIT_DECL, "No explicit declaration for %s from module %s. You should access it via interface call or use a require block.", name->string, mod_name); free_string_list(names); return to_ret; } // Otherwise, keep checking other names in this node } } free_string_list(names); return NULL; } struct check_result *check_module_if_call_in_optional(const struct check_data *data, const struct policy_node *node) { const struct if_call_data *if_data = node->data.ic_data; const char *if_mod_name = look_up_in_ifs_map(if_data->name); if (!if_mod_name) { // Not defined as an interface. Probably a macro return NULL; } if (0 == strcmp(if_mod_name, data->mod_name)) { // No issue calling interfaces in your own module return NULL; } const char *mod_type = look_up_in_mods_map(if_mod_name); if (!mod_type) { // If mod_type is NULL, we have no info on this module. We *should* have info // on all modules of type module, but in some cases may be missing ones that are // off or base. Off and base pass the check. return NULL; } if (0 == strcmp(mod_type, "base")) { // No issue calling interfaces in base module return NULL; } const struct policy_node *tmp = node; while (tmp->parent) { tmp = tmp->parent; if (tmp->flavor == NODE_OPTIONAL_POLICY) { return NULL; } } return make_check_result('W', W_ID_IF_CALL_OPTIONAL, "Call to interface %s defined in module %s should be in optional_policy block", if_data->name, if_mod_name); } struct check_result *check_empty_if_call_arg(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { if (!node->data.ic_data->args) { return make_check_result('W', W_ID_EMPTY_IF_CALL_ARG, "Call to interface %s with empty argument", node->data.ic_data->name); } return NULL; } struct check_result *check_space_if_call_arg(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { const struct string_list *prev = NULL, *args = node->data.ic_data->args; unsigned short i = 1; while (args) { if (args->has_incorrect_space) { // do not issue on mls ranges if (prev && (args->string[0] != '-' || look_up_in_decl_map(prev->string, DECL_TYPE) || look_up_in_decl_map(prev->string, DECL_ATTRIBUTE) || look_up_in_decl_map(prev->string, DECL_ROLE) || look_up_in_decl_map(prev->string, DECL_ATTRIBUTE_ROLE) || look_up_in_decl_map(prev->string, DECL_USER))) { return make_check_result('W', W_ID_SPACE_IF_CALL_ARG, "Argument no. %u '%s ...' of call to interface %s contains unquoted space", i - 1, // need to subtract one, cause it is the next string who has the flag set prev->string, node->data.ic_data->name); } } else { i++; } prev = args; args = args->next; } return NULL; } struct check_result *check_risky_allow_perm(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { // ignore non-allow rules if (node->data.av_data->flavor != AV_RULE_ALLOW) { return NULL; } const struct string_list *perms = node->data.av_data->perms; while (perms) { if (0 == strcmp(perms->string, "*") || 0 == strcmp(perms->string, "~")) { return make_check_result('W', W_ID_RISKY_ALLOW_PERM, "Allow rule with complement or wildcard permission"); } perms = perms->next; } return NULL; } struct check_result *check_module_file_name_mismatch(const struct check_data *data, const struct policy_node *node) { const char *mod_name = node->data.h_data->module_name; size_t mod_name_len = strlen(mod_name); const char *file_name = data->filename; size_t file_name_len = strlen(file_name); const char *file_name_ext = strrchr(file_name, '.'); if (file_name_ext) { file_name_len -= strlen(file_name_ext); } if (mod_name_len != file_name_len || strncmp(mod_name, file_name, file_name_len)) { return make_check_result('W', W_ID_MOD_NAME_FILE, "Module name %s does not match file name %s", mod_name, file_name); } return NULL; } static bool starts_with_module_prefix(const char *name) { for (const char *prefix = strchr(name, '_'); prefix; prefix = strchr(prefix + 1, '_')) { char *search_mod = strndup(name, (size_t)(prefix - name)); if (look_up_in_mods_map(search_mod)) { free(search_mod); return true; } for (size_t i = 0; i < (sizeof RefPol_module_abbreviations / sizeof *RefPol_module_abbreviations); ++i) { if (0 == strcmp(search_mod, RefPol_module_abbreviations[i][0]) && look_up_in_mods_map(RefPol_module_abbreviations[i][1])) { free(search_mod); return true; } } free(search_mod); } return false; } struct check_result *check_unknown_interface_call(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { const char *if_name = node->data.ic_data->name; // ignore known macros starting with module name for (size_t i = 0; i < (sizeof RefPol_macros_with_module_prefix / sizeof *RefPol_macros_with_module_prefix); ++i) { if (0 == strcmp(if_name, RefPol_macros_with_module_prefix[i])) { return NULL; } } // ignore calls which does not start with a module name: they are probably macros if (!starts_with_module_prefix(if_name)) { return NULL; } // ignore known interfaces if (look_up_in_ifs_map(if_name)) { return NULL; } return make_check_result('W', W_ID_UNKNOWN_CALL, "Call to %s can not be referenced to any interface", if_name); } struct check_result *check_declaration_interface_nameclash(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { const char *decl_name = node->data.d_data->name; if (look_up_in_ifs_map(decl_name)) { return make_check_result('E', E_ID_DECL_IF_CLASH, "Declaration with name %s clashes with same named interface", decl_name); } return NULL; } bool check_unknown_permission_condition() { // ignore if no permission or permission macro have been parsed if (permmacros_map_count() == 0) { printf("%sNote%s: Check E-007 is not performed because no permission macro has been parsed.\n", color_note(), color_reset()); return false; } if (decl_map_count(DECL_PERM) == 0) { printf("%sNote%s: Check E-007 is not performed because no permission has been parsed.\n", color_note(), color_reset()); return false; } return true; } struct check_result *check_unknown_permission(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { for (const struct string_list *cur = node->data.av_data->perms; cur; cur = cur->next) { if (0 == strcmp(cur->string, "*") || 0 == strcmp(cur->string, "~")) { continue; } // ignore generated all_ permission macros if (0 == strncmp(cur->string, "all_", strlen("all_")) && ends_with(cur->string, strlen(cur->string), "_perms", strlen("_perms"))) { continue; } if (look_up_in_decl_map(cur->string, DECL_PERM)) { // TODO: check if class supports this permission continue; } if (look_up_in_permmacros_map(cur->string)) { continue; } return make_check_result('E', E_ID_UNKNOWN_PERM, "Unknown permission %s used", cur->string); } return NULL; } bool check_unknown_class_condition() { // ignore if no class has been parsed if (decl_map_count(DECL_CLASS) == 0) { printf("%sNote%s: Check E-008 is not performed because no class has been parsed.\n", color_note(), color_reset()); return false; } return true; } struct check_result *check_unknown_class(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { const struct string_list *object_classes; switch (node->flavor) { case NODE_AV_RULE: object_classes = node->data.av_data->object_classes; break; case NODE_RT_RULE: object_classes = node->data.rt_data->object_classes; break; case NODE_TT_RULE: object_classes = node->data.tt_data->object_classes; break; default: return alloc_internal_error("Invalid node type for `check_unknown_class`"); } for (const struct string_list *cur = object_classes; cur; cur = cur->next) { // ignore interface parameters if (cur->string[0] == '$' && isdigit((unsigned char)cur->string[1])) { continue; } // ignore class sets if (ends_with(cur->string, strlen(cur->string), "_class_set", strlen("_class_set"))) { continue; } if (look_up_in_decl_map(cur->string, DECL_CLASS)) { continue; } return make_check_result('E', E_ID_UNKNOWN_CLASS, "Unknown class %s used", cur->string); } return NULL; } struct check_result *check_empty_block(__attribute__((unused)) const struct check_data *data, const struct policy_node *node) { for (const struct policy_node *cur = node->first_child; cur; cur = cur->next) { if (cur->flavor == NODE_START_BLOCK || cur->flavor == NODE_COMMENT || cur->flavor == NODE_SEMICOLON) { continue; } // found a statement return NULL; } return make_check_result('E', E_ID_EMPTY_BLOCK, "Empty block found"); } static const struct policy_node *is_ifelse_argument(const struct policy_node *cur) { for(; cur && cur->parent; cur = cur->parent) { if (cur->flavor == NODE_M4_ARG && cur->parent->flavor == NODE_IFELSE) { return cur; } } return NULL; } struct check_result *check_stray_word(const struct check_data *data, const struct policy_node *node) { const char *macro_name = node->data.str; if (str_in_sl(macro_name, data->config_check_data->custom_te_simple_macros)) { return NULL; } // ignore comparison arguments to ifelse // (do not ignore last node of block, which is never a comparison argument) const struct policy_node *ifelse_arument = is_ifelse_argument(node); if (ifelse_arument && ifelse_arument->next) { int position = 0; for (const struct policy_node *cur = ifelse_arument; cur->prev; cur = cur->prev) { position++; } position = position % 3; if ((position == 1 || position == 2)) { return NULL; } } return make_check_result('E', E_ID_STRAY_WORD, "Found stray word %s. If it is a simple m4 macro please add an selint-disable comment or ignore in the SELint configuration file.", macro_name); } selint-1.2.1/src/check_hooks.c0000644000175100001710000001764614167117255013171 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define _GNU_SOURCE #include #include #include #include #include "check_hooks.h" #include "color.h" int found_issue = 0; int suppress_output = 0; #define ALLOC_NODE(nl) if (ck->check_nodes[nl]) { \ loc = ck->check_nodes[nl]; \ while (loc->next) { loc = loc->next; } \ loc->next = malloc(sizeof(struct check_node)); \ if (!loc->next) { return SELINT_OUT_OF_MEM; } \ loc = loc->next; \ } else { \ ck->check_nodes[nl] = malloc(sizeof(struct check_node)); \ if (!ck->check_nodes[nl]) { return SELINT_OUT_OF_MEM; } \ loc = ck->check_nodes[nl]; \ } enum selint_error add_check(enum node_flavor check_flavor, struct checks *ck, const char *check_id, struct check_result *(*check_function)(const struct check_data *check_data, const struct policy_node *node)) { struct check_node *loc; ALLOC_NODE(check_flavor); loc->check_function = check_function; loc->check_id = strdup(check_id); loc->issues_found = 0; loc->next = NULL; return SELINT_SUCCESS; } enum selint_error call_checks(struct checks *ck, const struct check_data *data, const struct policy_node *node) { return call_checks_for_node_type(ck->check_nodes[node->flavor], data, node); } enum selint_error call_checks_for_node_type(struct check_node *ck_list, const struct check_data *data, const struct policy_node *node) { struct check_node *cur = ck_list; while (cur) { if (node->exceptions && strstr(node->exceptions, cur->check_id)) { cur = cur->next; continue; } struct check_result *res = cur->check_function(data, node); if (res) { found_issue = 1; cur->issues_found++; res->lineno = node->lineno; if (!suppress_output) { display_check_result(res, data); } free_check_result(res); } cur = cur->next; } return SELINT_SUCCESS; } void display_check_result(const struct check_result *res, const struct check_data *data) { static const size_t FILENAME_PADDING = 22; const size_t len = strlen(data->filename); unsigned int padding; if (FILENAME_PADDING < len) { padding = 0; } else { padding = (unsigned)(FILENAME_PADDING - len); } printf("%s:%*u: %s(%c)%s: %s (%c-%03u)\n", data->filename, padding, res->lineno, color_severity(res->severity), res->severity, color_reset(), res->message, res->severity, res->check_id); } struct check_result *alloc_internal_error(const char *string) { return make_check_result('F', F_ID_INTERNAL, "%s", string); } bool is_valid_severity(char check_char) { switch (check_char) { case 'C': case 'S': case 'W': case 'E': case 'F': return true; } return false; } int is_valid_check(const char *check_str) { if (!check_str) { return 0; } if (check_str[1] != '-') { return 0; } int max_id = 0; char severity = check_str[0]; switch (severity) { case 'C': max_id = C_END - 1; break; case 'S': max_id = S_END - 1; break; case 'W': max_id = W_END - 1; break; case 'E': max_id = E_END - 1; break; case 'F': max_id = 2; break; default: return 0; } int check_id = atoi(check_str+2); if (check_id > 0 && check_id <= max_id) { return 1; } else { return 0; } } // Return the number of check nodes in the checks structure static unsigned int count_check_nodes(const struct checks *ck) { unsigned int count = 0; for (int i=0; i <= NODE_ERROR; i++) { if (ck->check_nodes[i]) { struct check_node *cur = ck->check_nodes[i]; while (cur) { count++; cur = cur->next; } } } return count; } #define COMPARE_IDS(node1_id, node2_id)\ if (node1_id == node2_id) {\ return 0;\ } else {\ return (node1_id > node2_id?1:-1);\ } // Return negative if n1 goes before n2, positive if n1 goes after n2 or equal if they are equivalent static int comp_check_nodes(const void *n1, const void *n2) { const struct check_node *node1 = *(const struct check_node *const *)n1; const struct check_node *node2 = *(const struct check_node *const *)n2; int node1_id = atoi(node1->check_id + 2); int node2_id = atoi(node2->check_id + 2); switch (node1->check_id[0]) { case 'C': if (node2->check_id[0] == 'C') { COMPARE_IDS(node1_id, node2_id); } else { return -1; } case 'S': if (node2->check_id[0] == 'C') { return 1; } else if (node2->check_id[0] == 'S') { COMPARE_IDS(node1_id, node2_id); } else { return -1; } case 'W': if (node2->check_id[0] == 'C' || node2->check_id[0] == 'S') { return 1; } else if (node2->check_id[0] == 'W') { COMPARE_IDS(node1_id, node2_id); } else { return -1; } case 'E': if (node2->check_id[0] == 'E') { COMPARE_IDS(node1_id, node2_id); } else { return 1; } default: return 0; //Should never happen, but no way to return an error } } void display_check_issue_counts(const struct checks *ck) { size_t num_nodes = count_check_nodes(ck); unsigned int printed_something = 0; // Build flat array of check nodes struct check_node **node_arr = calloc(num_nodes, sizeof(struct check_node *)); unsigned int node_arr_index = 0; for (int i=0; i <= NODE_ERROR; i++) { if (ck->check_nodes[i]) { struct check_node *cur = ck->check_nodes[i]; while (cur) { node_arr[node_arr_index] = cur; cur = cur->next; node_arr_index++; } } } qsort((void *) node_arr, num_nodes, sizeof(struct check_node *), comp_check_nodes); unsigned int issue_count = 0; char *old_issue_name = NULL; for (unsigned int i=0; i < num_nodes; i++) { if (old_issue_name && 0 != strcmp(old_issue_name, node_arr[i]->check_id)) { // New issue. Print the old info if (issue_count != 0) { printf("%s%s%s: %u\n", color_severity(old_issue_name[0]), old_issue_name, color_reset(), issue_count); printed_something = 1; } // Start counting new issue_count = node_arr[i]->issues_found; } else { // Same issue as previous element issue_count += node_arr[i]->issues_found; } old_issue_name = node_arr[i]->check_id; } // Possible print last issue if (issue_count != 0) { printf("%s%s%s: %u\n", color_severity(old_issue_name[0]), old_issue_name, color_reset(), issue_count); printed_something = 1; } if (!printed_something) { printf("%s(none)%s\n", color_ok(), color_reset()); } free(node_arr); } void free_check_result(struct check_result *res) { if (res) { free(res->message); } free(res); } struct check_result *make_check_result(char severity, unsigned int check_id, const char *format, ...) { struct check_result *res = malloc(sizeof(struct check_result)); res->severity = severity; res->check_id = check_id; va_list args; va_start(args, format); if (vasprintf(&res->message, format, args) == -1) { res->severity = 'F'; res->check_id = F_ID_INTERNAL; res->message = strdup("Failed to generate check result message"); } va_end(args); return res; } void free_checks(struct checks *to_free) { if (to_free == NULL) { return; } for (int i=0; i < NODE_ERROR + 1; i++) { free_check_node(to_free->check_nodes[i]); } free(to_free); } void free_check_node(struct check_node *to_free) { while (to_free) { struct check_node *tmp = to_free; to_free = to_free->next; free(tmp->check_id); free(tmp); } } selint-1.2.1/src/lex.c0000644000175100001710000025036414167117371011474 00000000000000 #line 3 "lex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yyget_lval #define yyget_lval_ALREADY_DEFINED #else #define yyget_lval yyget_lval #endif #ifdef yyset_lval #define yyset_lval_ALREADY_DEFINED #else #define yyset_lval yyset_lval #endif #ifdef yyget_lloc #define yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc yyget_lloc #endif #ifdef yyset_lloc #define yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc yyset_lloc #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires * access to the local variable yy_act. Since yyless() is a macro, it would break * existing scanners that call yyless() from OUTSIDE yylex. * One obvious solution it to make yy_act a global. I tried that, and saw * a 5% performance hit in a non-yylineno scanner, because yy_act is * normally declared as a register variable-- so it is not worth it. */ #define YY_LESS_LINENO(n) \ do { \ int yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ }while(0) #define YY_LINENO_REWIND_TO(dst) \ do {\ const char *p;\ for ( p = yy_cp-1; p >= (dst); --p)\ if ( *p == '\n' )\ --yylineno;\ }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) #define yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 89 #define YY_END_OF_BUFFER 90 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[501] = { 0, 0, 0, 90, 88, 87, 87, 82, 88, 88, 59, 88, 74, 65, 66, 76, 67, 77, 68, 58, 71, 72, 88, 59, 80, 73, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 69, 88, 70, 75, 81, 63, 0, 0, 85, 0, 59, 78, 0, 60, 0, 58, 0, 60, 0, 62, 83, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 37, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 79, 0, 64, 57, 58, 60, 62, 62, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 42, 59, 59, 59, 59, 0, 0, 57, 58, 60, 62, 62, 59, 59, 59, 59, 59, 7, 59, 59, 59, 0, 86, 59, 59, 38, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 10, 59, 59, 3, 59, 0, 57, 57, 0, 58, 62, 0, 62, 5, 13, 59, 59, 34, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 39, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 11, 59, 0, 0, 57, 57, 62, 0, 62, 59, 59, 59, 35, 49, 59, 59, 59, 59, 59, 59, 59, 59, 32, 40, 59, 59, 2, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 61, 57, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 45, 59, 59, 59, 43, 59, 59, 30, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 61, 57, 0, 0, 59, 59, 59, 59, 59, 59, 28, 59, 59, 59, 50, 41, 36, 59, 44, 59, 59, 59, 59, 59, 59, 59, 59, 55, 59, 59, 59, 59, 59, 59, 59, 59, 0, 61, 0, 0, 59, 6, 59, 17, 59, 59, 59, 59, 59, 59, 54, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 4, 59, 59, 59, 0, 62, 0, 14, 59, 15, 59, 59, 59, 59, 59, 59, 59, 19, 59, 52, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 53, 59, 0, 62, 59, 59, 59, 48, 59, 59, 51, 27, 29, 59, 59, 59, 59, 59, 59, 59, 59, 23, 22, 59, 59, 59, 0, 62, 59, 59, 59, 46, 47, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 59, 59, 59, 59, 59, 1, 59, 33, 59, 9, 59, 59, 8, 59, 0, 12, 59, 18, 59, 59, 59, 59, 31, 59, 59, 0, 16, 20, 26, 59, 25, 21, 59, 0, 24, 56, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 9, 1, 10, 11, 12, 13, 14, 1, 15, 16, 17, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 21, 1, 22, 1, 1, 1, 23, 23, 24, 23, 24, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 25, 9, 9, 9, 1, 1, 1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 9, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 9, 53, 54, 55, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[57] = { 0, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 4, 1, 3, 5, 4, 6, 7, 1, 1, 6, 6, 3, 1, 3, 1, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 2 } ; static const flex_int16_t yy_base[511] = { 0, 0, 0, 719, 720, 720, 720, 696, 710, 54, 0, 706, 720, 720, 720, 720, 720, 42, 720, 84, 695, 720, 692, 100, 720, 720, 20, 671, 21, 28, 673, 665, 677, 30, 667, 33, 665, 44, 47, 670, 45, 660, 720, 651, 720, 720, 720, 720, 697, 700, 720, 59, 0, 720, 77, 67, 683, 118, 681, 77, 680, 679, 720, 134, 72, 651, 665, 654, 666, 654, 659, 653, 650, 644, 662, 647, 58, 59, 655, 63, 654, 638, 639, 82, 642, 92, 643, 649, 640, 638, 635, 644, 720, 122, 720, 126, 150, 127, 656, 120, 166, 646, 632, 628, 635, 632, 624, 629, 631, 200, 620, 633, 617, 71, 631, 624, 630, 628, 627, 611, 621, 624, 623, 618, 614, 616, 605, 616, 607, 601, 615, 0, 604, 617, 612, 599, 119, 624, 143, 158, 171, 622, 240, 621, 594, 589, 601, 590, 0, 590, 593, 593, 630, 720, 0, 603, 0, 585, 231, 584, 595, 582, 594, 581, 580, 585, 589, 577, 590, 578, 582, 587, 586, 583, 573, 577, 143, 574, 582, 236, 579, 151, 250, 251, 591, 254, 589, 589, 264, 0, 556, 576, 576, 0, 563, 570, 554, 568, 558, 557, 565, 549, 550, 564, 0, 561, 559, 555, 557, 557, 558, 559, 545, 545, 539, 532, 541, 555, 542, 535, 532, 531, 548, 537, 246, 147, 533, 0, 541, 255, 554, 268, 271, 552, 272, 255, 528, 522, 530, 0, 0, 536, 540, 524, 524, 520, 522, 529, 519, 0, 0, 513, 530, 0, 516, 518, 515, 526, 508, 526, 511, 504, 513, 516, 503, 500, 499, 512, 508, 510, 497, 504, 493, 491, 508, 289, 518, 277, 517, 516, 278, 501, 486, 493, 494, 108, 491, 482, 480, 498, 481, 484, 478, 492, 481, 482, 0, 481, 482, 478, 0, 472, 485, 0, 486, 469, 480, 485, 482, 470, 480, 479, 462, 465, 457, 277, 485, 484, 281, 485, 456, 467, 457, 451, 142, 468, 0, 463, 458, 464, 0, 0, 0, 460, 0, 450, 464, 441, 447, 459, 435, 445, 448, 0, 441, 442, 452, 440, 434, 442, 446, 442, 296, 720, 457, 284, 435, 447, 423, 421, 425, 441, 422, 417, 422, 427, 0, 415, 421, 430, 430, 420, 410, 413, 428, 415, 421, 422, 408, 0, 423, 406, 424, 261, 431, 432, 0, 403, 396, 403, 407, 403, 396, 395, 408, 407, 388, 396, 0, 389, 390, 406, 397, 385, 393, 398, 385, 392, 380, 0, 385, 99, 407, 383, 381, 390, 0, 376, 376, 0, 0, 0, 377, 380, 379, 380, 371, 368, 367, 376, 0, 0, 365, 364, 365, 301, 720, 370, 375, 362, 0, 0, 373, 368, 371, 356, 361, 364, 367, 368, 361, 364, 369, 303, 362, 349, 353, 347, 337, 0, 318, 0, 308, 0, 297, 306, 0, 314, 305, 0, 306, 0, 305, 274, 279, 278, 0, 276, 273, 173, 0, 0, 0, 42, 0, 0, 30, 310, 0, 0, 315, 307, 308, 309, 720, 327, 319, 313, 317, 322, 720, 351, 358, 363, 367, 369, 371, 373, 375, 382, 384 } ; static const flex_int16_t yy_def[511] = { 0, 500, 1, 500, 500, 500, 500, 500, 501, 502, 503, 500, 500, 500, 500, 500, 500, 500, 500, 504, 505, 500, 500, 503, 500, 500, 23, 23, 23, 23, 23, 23, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 500, 500, 500, 500, 500, 500, 501, 502, 500, 502, 503, 500, 500, 504, 500, 504, 505, 57, 505, 506, 500, 23, 503, 503, 503, 503, 503, 503, 63, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 500, 502, 500, 500, 57, 96, 507, 506, 63, 503, 503, 503, 503, 503, 503, 503, 100, 500, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 500, 504, 504, 508, 507, 503, 503, 503, 503, 503, 503, 503, 503, 503, 509, 500, 109, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 500, 500, 504, 510, 500, 508, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 500, 500, 505, 500, 510, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 500, 500, 500, 500, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 500, 500, 500, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 500, 500, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 500, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 500, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 502, 503, 503, 503, 503, 503, 503, 503, 502, 503, 503, 502, 502, 502, 502, 500, 502, 502, 502, 502, 502, 0, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500 } ; static const flex_int16_t yy_nxt[777] = { 0, 4, 5, 6, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 10, 19, 20, 21, 22, 23, 23, 10, 24, 4, 25, 26, 27, 28, 29, 30, 31, 32, 10, 33, 10, 10, 34, 35, 36, 37, 10, 38, 39, 40, 41, 10, 10, 10, 10, 42, 43, 44, 45, 50, 54, 64, 68, 70, 50, 69, 76, 489, 79, 65, 66, 71, 72, 77, 54, 54, 54, 80, 84, 82, 88, 94, 85, 54, 94, 488, 500, 54, 83, 500, 54, 86, 114, 115, 93, 89, 500, 117, 97, 90, 158, 116, 51, 56, 50, 57, 58, 159, 118, 59, 59, 101, 120, 102, 121, 59, 59, 59, 59, 59, 59, 63, 58, 125, 50, 63, 63, 50, 128, 126, 435, 63, 63, 63, 63, 63, 63, 56, 129, 96, 58, 142, 99, 97, 97, 137, 500, 138, 140, 97, 97, 97, 97, 97, 97, 100, 50, 324, 181, 100, 100, 325, 137, 136, 183, 100, 100, 100, 100, 100, 100, 139, 220, 360, 221, 140, 140, 184, 50, 185, 58, 140, 140, 140, 140, 140, 140, 143, 271, 361, 500, 143, 143, 58, 229, 487, 272, 143, 143, 143, 143, 143, 143, 152, 152, 153, 152, 152, 152, 152, 152, 154, 152, 152, 152, 152, 154, 152, 154, 152, 154, 154, 152, 152, 152, 154, 154, 154, 152, 154, 152, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 152, 152, 152, 152, 187, 50, 188, 99, 198, 199, 224, 50, 225, 226, 230, 137, 231, 232, 184, 187, 185, 500, 99, 200, 268, 201, 202, 50, 187, 227, 235, 99, 230, 269, 277, 278, 279, 232, 280, 50, 270, 230, 279, 317, 319, 354, 50, 355, 354, 275, 385, 50, 315, 50, 411, 50, 352, 50, 50, 494, 50, 486, 490, 50, 485, 50, 484, 50, 483, 50, 492, 495, 494, 482, 493, 493, 498, 50, 453, 496, 383, 491, 491, 499, 495, 479, 491, 491, 499, 468, 497, 497, 481, 480, 478, 477, 476, 475, 497, 497, 48, 48, 474, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 52, 52, 473, 52, 55, 55, 55, 55, 55, 60, 60, 98, 98, 141, 141, 186, 186, 152, 152, 152, 152, 152, 152, 152, 233, 233, 472, 471, 470, 469, 467, 466, 465, 464, 463, 462, 461, 460, 459, 458, 457, 456, 455, 454, 452, 451, 450, 449, 448, 447, 446, 445, 444, 443, 442, 441, 440, 439, 438, 437, 436, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 413, 354, 412, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 384, 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, 363, 362, 359, 358, 357, 356, 279, 317, 353, 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 323, 322, 321, 320, 318, 317, 316, 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 281, 99, 276, 274, 273, 267, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 234, 99, 232, 228, 223, 222, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 197, 196, 153, 195, 194, 193, 192, 191, 190, 189, 58, 99, 182, 180, 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, 157, 156, 155, 151, 150, 149, 148, 147, 146, 145, 144, 99, 135, 134, 133, 132, 131, 130, 127, 124, 123, 122, 119, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 99, 61, 61, 95, 50, 47, 92, 91, 87, 81, 78, 75, 74, 73, 67, 62, 61, 53, 47, 46, 500, 3, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500 } ; static const flex_int16_t yy_chk[777] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 17, 26, 28, 29, 51, 28, 33, 486, 35, 26, 26, 29, 29, 33, 17, 17, 17, 35, 38, 37, 40, 54, 38, 17, 54, 483, 55, 17, 37, 55, 17, 38, 76, 76, 51, 40, 59, 77, 59, 40, 113, 76, 9, 19, 411, 19, 19, 113, 77, 19, 19, 64, 79, 64, 79, 19, 19, 19, 19, 19, 19, 23, 23, 83, 136, 23, 23, 93, 85, 83, 411, 23, 23, 23, 23, 23, 23, 57, 85, 57, 57, 99, 99, 57, 57, 95, 97, 95, 97, 57, 57, 57, 57, 57, 57, 63, 181, 285, 136, 63, 63, 285, 138, 93, 138, 63, 63, 63, 63, 63, 63, 96, 176, 324, 176, 96, 96, 139, 479, 139, 139, 96, 96, 96, 96, 96, 96, 100, 225, 324, 140, 100, 100, 140, 181, 479, 225, 100, 100, 100, 100, 100, 100, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 142, 229, 142, 142, 158, 158, 179, 383, 179, 179, 182, 183, 182, 183, 185, 235, 185, 185, 235, 158, 224, 158, 158, 315, 188, 179, 188, 188, 231, 224, 231, 232, 234, 232, 234, 275, 224, 277, 280, 277, 280, 318, 352, 318, 355, 229, 355, 435, 275, 453, 383, 468, 315, 491, 492, 493, 487, 478, 487, 497, 477, 490, 475, 498, 474, 496, 491, 493, 499, 473, 492, 493, 497, 495, 435, 495, 352, 487, 487, 498, 499, 468, 490, 490, 499, 453, 496, 496, 472, 470, 467, 465, 464, 462, 495, 495, 501, 501, 460, 501, 501, 501, 502, 502, 502, 502, 502, 502, 502, 503, 503, 458, 503, 504, 504, 504, 504, 504, 505, 505, 506, 506, 507, 507, 508, 508, 509, 509, 509, 509, 509, 509, 509, 510, 510, 457, 456, 455, 454, 452, 451, 450, 449, 448, 447, 446, 445, 444, 443, 442, 439, 438, 437, 434, 433, 432, 429, 428, 427, 426, 425, 424, 423, 422, 418, 417, 415, 414, 413, 412, 410, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 397, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 385, 384, 382, 381, 380, 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, 368, 367, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 354, 351, 350, 349, 348, 347, 346, 345, 344, 342, 341, 340, 339, 338, 337, 336, 335, 333, 329, 328, 327, 325, 323, 322, 321, 320, 319, 317, 316, 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, 302, 301, 299, 298, 297, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 284, 283, 282, 281, 279, 278, 276, 274, 273, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, 252, 251, 248, 247, 246, 245, 244, 243, 242, 241, 238, 237, 236, 233, 230, 228, 226, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, 192, 191, 190, 187, 186, 184, 180, 178, 177, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, 157, 155, 152, 151, 150, 149, 147, 146, 145, 144, 143, 141, 137, 135, 134, 133, 132, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 112, 111, 110, 108, 107, 106, 105, 104, 103, 102, 101, 98, 91, 90, 89, 88, 87, 86, 84, 82, 81, 80, 78, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 61, 60, 58, 56, 49, 48, 43, 41, 39, 36, 34, 32, 31, 30, 27, 22, 20, 11, 8, 7, 3, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500 } ; /* Table of booleans, true if rule could match eol. */ static const flex_int32_t yy_rule_can_match_eol[90] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "lex.l" /* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #line 17 "lex.l" #include #include #include "tree.h" #include "parse.h" extern void reset_current_lines(void); /* * Callback by the lexer, called prior to every matched rule's action. * Update the source file location accordingly. */ #define YY_USER_ACTION \ yylloc->first_line = yylloc->last_line = yylineno; \ yylloc->first_column = yycolumn; \ yylloc->last_column = yycolumn + yyleng - 1; \ yycolumn += yyleng; // used by parser char* current_lines[LINES_TO_CACHE] = { NULL }; unsigned line_cache_index = 0; // internal state for cached lines static size_t current_lines_alloc[LINES_TO_CACHE] = { 0 }; static size_t current_line_sent = 0; static size_t current_line_len = 0; void reset_current_lines(void) { for (unsigned i = 0; i < LINES_TO_CACHE; ++i) { free(current_lines[i]); current_lines[i] = NULL; current_lines_alloc[i] = 0; } line_cache_index = 0; current_line_sent = current_line_len = 0; } /* * Override the input method of the lexer. * Read a complete line and save it for error printing. * Must be a macro to access yyin. */ #undef YY_INPUT #define YY_INPUT(buf, result, max_size) \ size_t _avail = current_line_len - current_line_sent; \ if (_avail == 0) { \ current_line_sent = 0; \ line_cache_index = (line_cache_index + 1) % LINES_TO_CACHE; \ const ssize_t _res = getline(¤t_lines[line_cache_index], \ ¤t_lines_alloc[line_cache_index], \ yyin); \ if (_res < 0) { \ if (ferror(yyin)) { \ YY_FATAL_ERROR("Error reading input"); \ } \ _avail = 0; \ current_lines[line_cache_index][0] = '\0'; \ } else { \ _avail = (size_t)_res; \ } \ current_line_len = _avail; \ } \ if (_avail > (size_t)(max_size)) { \ _avail = (size_t)(max_size); \ } \ memcpy((buf), current_lines[line_cache_index] + current_line_sent, _avail); \ current_line_sent += _avail; \ (result) = (int)_avail; #line 893 "lex.c" #define YY_NO_INPUT 1 #line 895 "lex.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; YYLTYPE * yylloc_r; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r # define yylloc yyg->yylloc_r int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; yylloc = yylloc_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 95 "lex.l" #line 1179 "lex.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 501 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 720 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) { int yyl; for ( yyl = 0; yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) do{ yylineno++; yycolumn=0; }while(0) ; } do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 96 "lex.l" { return POLICY_MODULE; } YY_BREAK case 2: YY_RULE_SETUP #line 97 "lex.l" { return MODULE; } YY_BREAK case 3: YY_RULE_SETUP #line 98 "lex.l" { return TYPE; } YY_BREAK case 4: YY_RULE_SETUP #line 99 "lex.l" { return TYPEALIAS; } YY_BREAK case 5: YY_RULE_SETUP #line 100 "lex.l" { return ALIAS; } YY_BREAK case 6: YY_RULE_SETUP #line 101 "lex.l" { return ATTRIBUTE; } YY_BREAK case 7: YY_RULE_SETUP #line 102 "lex.l" { return BOOL; } YY_BREAK case 8: YY_RULE_SETUP #line 103 "lex.l" { return TYPE_ATTRIBUTE; } YY_BREAK case 9: YY_RULE_SETUP #line 104 "lex.l" { return ROLE_ATTRIBUTE; } YY_BREAK case 10: YY_RULE_SETUP #line 105 "lex.l" { return ROLE; } YY_BREAK case 11: YY_RULE_SETUP #line 106 "lex.l" { return TYPES; } YY_BREAK case 12: YY_RULE_SETUP #line 107 "lex.l" { return ATTRIBUTE_ROLE; } YY_BREAK case 13: YY_RULE_SETUP #line 108 "lex.l" { return ALLOW; } YY_BREAK case 14: YY_RULE_SETUP #line 109 "lex.l" { return ALLOW_XPERM; } YY_BREAK case 15: YY_RULE_SETUP #line 110 "lex.l" { return AUDIT_ALLOW; } YY_BREAK case 16: YY_RULE_SETUP #line 111 "lex.l" { return AUDIT_ALLOW_XPERM; } YY_BREAK case 17: YY_RULE_SETUP #line 112 "lex.l" { return DONT_AUDIT; } YY_BREAK case 18: YY_RULE_SETUP #line 113 "lex.l" { return DONT_AUDIT_XPERM; } YY_BREAK case 19: YY_RULE_SETUP #line 114 "lex.l" { return NEVER_ALLOW; } YY_BREAK case 20: YY_RULE_SETUP #line 115 "lex.l" { return NEVER_ALLOW_XPERM; } YY_BREAK case 21: YY_RULE_SETUP #line 116 "lex.l" { return TYPE_TRANSITION; } YY_BREAK case 22: YY_RULE_SETUP #line 117 "lex.l" { return TYPE_MEMBER; } YY_BREAK case 23: YY_RULE_SETUP #line 118 "lex.l" { return TYPE_CHANGE; } YY_BREAK case 24: YY_RULE_SETUP #line 119 "lex.l" { return RANGE_TRANSITION; } YY_BREAK case 25: YY_RULE_SETUP #line 120 "lex.l" { return ROLE_TRANSITION; } YY_BREAK case 26: YY_RULE_SETUP #line 121 "lex.l" { return OPTIONAL_POLICY; } YY_BREAK case 27: YY_RULE_SETUP #line 122 "lex.l" { return GEN_REQUIRE; } YY_BREAK case 28: YY_RULE_SETUP #line 123 "lex.l" { return GEN_BOOL; } YY_BREAK case 29: YY_RULE_SETUP #line 124 "lex.l" { return GEN_TUNABLE; } YY_BREAK case 30: YY_RULE_SETUP #line 125 "lex.l" { return REQUIRE; } YY_BREAK case 31: YY_RULE_SETUP #line 126 "lex.l" { return TUNABLE_POLICY; } YY_BREAK case 32: YY_RULE_SETUP #line 127 "lex.l" { return IFELSE; } YY_BREAK case 33: YY_RULE_SETUP #line 128 "lex.l" { return REFPOLICYWARN; } YY_BREAK case 34: YY_RULE_SETUP #line 129 "lex.l" { return CLASS; } YY_BREAK case 35: YY_RULE_SETUP #line 130 "lex.l" { return COMMON; } YY_BREAK case 36: YY_RULE_SETUP #line 131 "lex.l" { return INHERITS; } YY_BREAK case 37: YY_RULE_SETUP #line 132 "lex.l" { return IF; } YY_BREAK case 38: YY_RULE_SETUP #line 133 "lex.l" { return ELSE; } YY_BREAK case 39: YY_RULE_SETUP #line 134 "lex.l" { return IFDEF; } YY_BREAK case 40: YY_RULE_SETUP #line 135 "lex.l" { return IFNDEF; } YY_BREAK case 41: YY_RULE_SETUP #line 136 "lex.l" { return GENFSCON; } YY_BREAK case 42: YY_RULE_SETUP #line 137 "lex.l" { return SID; } YY_BREAK case 43: YY_RULE_SETUP #line 138 "lex.l" { return PORTCON; } YY_BREAK case 44: YY_RULE_SETUP #line 139 "lex.l" { return NETIFCON; } YY_BREAK case 45: YY_RULE_SETUP #line 140 "lex.l" { return NODECON; } YY_BREAK case 46: YY_RULE_SETUP #line 141 "lex.l" { return FS_USE_TRANS; } YY_BREAK case 47: YY_RULE_SETUP #line 142 "lex.l" { return FS_USE_XATTR; } YY_BREAK case 48: YY_RULE_SETUP #line 143 "lex.l" { return FS_USE_TASK; } YY_BREAK case 49: YY_RULE_SETUP #line 144 "lex.l" { return DEFINE; } YY_BREAK case 50: YY_RULE_SETUP #line 145 "lex.l" { return GEN_USER; } YY_BREAK case 51: YY_RULE_SETUP #line 146 "lex.l" { return GEN_CONTEXT; } YY_BREAK case 52: YY_RULE_SETUP #line 147 "lex.l" { return PERMISSIVE; } YY_BREAK case 53: YY_RULE_SETUP #line 148 "lex.l" { return TYPEBOUNDS; } YY_BREAK case 54: YY_RULE_SETUP #line 149 "lex.l" { return INTERFACE; } YY_BREAK case 55: YY_RULE_SETUP #line 150 "lex.l" { return TEMPLATE; } YY_BREAK case 56: YY_RULE_SETUP #line 151 "lex.l" { return USERDEBUG_OR_ENG; } YY_BREAK case 57: YY_RULE_SETUP #line 152 "lex.l" { yylval->string = strdup(yytext); return VERSION_NO; } YY_BREAK case 58: YY_RULE_SETUP #line 153 "lex.l" { yylval->string = strdup(yytext); return NUMBER; } YY_BREAK case 59: YY_RULE_SETUP #line 154 "lex.l" { yylval->string = strdup(yytext); return STRING; } YY_BREAK case 60: YY_RULE_SETUP #line 155 "lex.l" { yylval->string = strdup(yytext); return NUM_STRING; } YY_BREAK case 61: YY_RULE_SETUP #line 156 "lex.l" { yylval->string = strdup(yytext); return IPV4; } YY_BREAK case 62: YY_RULE_SETUP #line 157 "lex.l" { yylval->string = strdup(yytext); return IPV6; } YY_BREAK case 63: YY_RULE_SETUP #line 158 "lex.l" { yylval->string = strdup(yytext); return QUOTED_STRING; } YY_BREAK case 64: YY_RULE_SETUP #line 159 "lex.l" { return FILE_TYPE_SPECIFIER; } YY_BREAK case 65: YY_RULE_SETUP #line 160 "lex.l" { return OPEN_PAREN; } YY_BREAK case 66: YY_RULE_SETUP #line 161 "lex.l" { return CLOSE_PAREN; } YY_BREAK case 67: YY_RULE_SETUP #line 162 "lex.l" { return COMMA; } YY_BREAK case 68: YY_RULE_SETUP #line 163 "lex.l" { return PERIOD; } YY_BREAK case 69: YY_RULE_SETUP #line 164 "lex.l" { return OPEN_CURLY; } YY_BREAK case 70: YY_RULE_SETUP #line 165 "lex.l" { return CLOSE_CURLY; } YY_BREAK case 71: YY_RULE_SETUP #line 166 "lex.l" { return COLON; } YY_BREAK case 72: YY_RULE_SETUP #line 167 "lex.l" { return SEMICOLON; } YY_BREAK case 73: YY_RULE_SETUP #line 168 "lex.l" { return BACKTICK; } YY_BREAK case 74: YY_RULE_SETUP #line 169 "lex.l" { return SINGLE_QUOTE; } YY_BREAK case 75: YY_RULE_SETUP #line 170 "lex.l" { return TILDA; } YY_BREAK case 76: YY_RULE_SETUP #line 171 "lex.l" { return STAR; } YY_BREAK case 77: YY_RULE_SETUP #line 172 "lex.l" { return DASH; } YY_BREAK case 78: YY_RULE_SETUP #line 173 "lex.l" { return AND; } YY_BREAK case 79: YY_RULE_SETUP #line 174 "lex.l" { return OR; } YY_BREAK case 80: YY_RULE_SETUP #line 175 "lex.l" { return XOR; } YY_BREAK case 81: YY_RULE_SETUP #line 176 "lex.l" { return NOT_EQUAL; } YY_BREAK case 82: YY_RULE_SETUP #line 177 "lex.l" { return NOT; } YY_BREAK case 83: YY_RULE_SETUP #line 178 "lex.l" { return EQUAL; } YY_BREAK case 84: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 179 "lex.l" { yylval->string = strdup(yytext); return SELINT_COMMAND; } YY_BREAK case 85: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 180 "lex.l" { return COMMENT; } YY_BREAK case 86: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 181 "lex.l" ; /* skip m4 comment lines */ YY_BREAK case 87: /* rule 87 can match eol */ YY_RULE_SETUP #line 182 "lex.l" ; /* normally skip whitespace */ YY_BREAK case 88: YY_RULE_SETUP #line 183 "lex.l" { yylval->symbol = *yytext; return UNKNOWN_TOKEN; } YY_BREAK case 89: YY_RULE_SETUP #line 184 "lex.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1703 "lex.c" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 501 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 501 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 500); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; if ( c == '\n' ) do{ yylineno++; yycolumn=0; }while(0) ; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * yyget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } YYLTYPE *yyget_lloc (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 184 "lex.l" selint-1.2.1/src/perm_macro.h0000644000175100001710000000254514167117255013032 00000000000000/* * Copyright 2020 The SELint Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef PERMMACRO_H #define PERMMACRO_H #include "string_list.h" /********************************************* * permmacro_check * Performs a check on the given class and permissions whether a declared * permission-macro can be used to simplify the used permissions. * e.g. file:{ open read } leads to read_file_perms being suggested * class (in) - The related class * permissions (in) - The currently used permissions * Returns - a string containing a message (which needs to be freed) or NULL. *********************************************/ char *permmacro_check(const char *class, const struct string_list *permissions); /********************************************* * Free internal allocations *********************************************/ void free_permmacros(void); #endif selint-1.2.1/src/parse_fc.c0000644000175100001710000001423114167117255012456 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "parse_fc.h" #include "tree.h" // "gen_context(" #define GEN_CONTEXT_LEN 12 struct fc_entry *parse_fc_line(char *line) { const char *whitespace = " \t"; struct fc_entry *out = malloc(sizeof(struct fc_entry)); memset(out, 0, sizeof(struct fc_entry)); char *orig_line = strdup(line); // If the object class is omitted, we need to revert char *pos = strtok(line, whitespace); if (pos == NULL) { goto cleanup; } out->path = strdup(pos); pos = strtok(NULL, whitespace); if (pos == NULL) { goto cleanup; } if (pos[0] == '-') { if (pos[2] != '\0') { goto cleanup; } out->obj = pos[1]; pos = strtok(NULL, whitespace); if (pos == NULL) { goto cleanup; } } // pos points to the start of the context, but spaces in the context may have been // overwritten by strtok strcpy(line, orig_line); if (strncmp("gen_context(", pos, GEN_CONTEXT_LEN) == 0) { pos += GEN_CONTEXT_LEN; // Next character char *context_part = strtok(pos, ","); if (context_part == NULL) { goto cleanup; } char *maybe_s = strtok(NULL, ","); char *maybe_c = NULL; int i = 0; if (maybe_s) { maybe_c = strtok(NULL, ","); while (maybe_s[i] != '\0' && maybe_s[i] != ')') { i++; } if (maybe_s[i] == '\0') { if (!maybe_c) { // Missing closing paren goto cleanup; } } maybe_s[i] = '\0'; while (maybe_s[0] != '\0' && (maybe_s[0] == ' ' || maybe_s[0] == '\t')) { // trim beginning whitespace maybe_s++; } } else { // No mls while (context_part[i] != '\0' && context_part[i] != ')') { i++; } if (context_part[i] == '\0') { // Missing closing paren goto cleanup; } context_part[i] = '\0'; } if (maybe_c) { while (maybe_c[i] != '\0' && maybe_c[i] != ')') { i++; } if (maybe_c[i] == '\0') { // Missing closing paren goto cleanup; } maybe_c[i] = '\0'; while (maybe_c[0] != '\0' && (maybe_c[0] == ' ' || maybe_c[0] == '\t')) { // trim beginning whitespace maybe_c++; } } out->context = parse_context(context_part); if (out->context == NULL) { goto cleanup; } out->context->has_gen_context = 1; if (maybe_c) { out->context->range = malloc(strlen(maybe_s) + 1 + strlen(maybe_c) + 1); strcpy(out->context->range, maybe_s); strcat(out->context->range, ":"); strcat(out->context->range, maybe_c); } else if (maybe_s) { out->context->range = strdup(maybe_s); } else { out->context->range = NULL; } } else if (strcmp("<>\n", pos) == 0 || strcmp("<>\r\n", pos) == 0) { out->context = NULL; } else { out->context = parse_context(pos); if (out->context == NULL) { goto cleanup; } out->context->has_gen_context = 0; } free(orig_line); return out; cleanup: free(orig_line); free_fc_entry(out); return NULL; } struct sel_context *parse_context(char *context_str) { if (strchr(context_str, '(')) { return NULL; } struct sel_context *context = malloc(sizeof(struct sel_context)); memset(context, 0, sizeof(struct sel_context)); // User char *pos = strtok(context_str, ":"); if (pos == NULL) { goto cleanup; } context->user = strdup(pos); // Role pos = strtok(NULL, ":"); if (pos == NULL) { goto cleanup; } context->role = strdup(pos); // Type pos = strtok(NULL, ":"); if (pos == NULL) { goto cleanup; } context->type = strdup(pos); pos = strtok(NULL, ":"); if (pos) { context->range = strdup(pos); if (strtok(NULL, ":")) { goto cleanup; } } return context; cleanup: free_sel_context(context); return NULL; } bool check_for_fc_macro(const char *line, const struct string_list *custom_fc_macros) { if (!custom_fc_macros) { return false; } size_t line_len = strlen(line); for (;custom_fc_macros; custom_fc_macros = custom_fc_macros->next){ size_t custom_fc_len = strlen(custom_fc_macros->string); if (line_len <= custom_fc_len) { continue; } if (line[custom_fc_len] != '(') { continue; } if (0 == strncmp(line, custom_fc_macros->string, custom_fc_len)) { return true; } } return false; } struct policy_node *parse_fc_file(const char *filename, const struct string_list *custom_fc_macros) { FILE *fd = fopen(filename, "r"); if (!fd) { return NULL; } struct policy_node *head = malloc(sizeof(struct policy_node)); memset(head, 0, sizeof(struct policy_node)); head->flavor = NODE_FC_FILE; struct policy_node *cur = head; char *line = NULL; ssize_t len_read = 0; size_t buf_len = 0; unsigned int lineno = 0; while ((len_read = getline(&line, &buf_len, fd)) != -1) { lineno++; if (len_read <= 1 || line[0] == '#') { continue; } // Skip over m4 constructs if (strncmp(line, "ifdef", 5) == 0 || strncmp(line, "ifndef", 6) == 0 || strncmp(line, "')", 2) == 0 || strncmp(line, "', `", 4) == 0 || strncmp(line, "',`", 3) == 0) { continue; } // TODO: Right now whitespace parses as an error // We may want to detect it and report a lower severity issue if (check_for_fc_macro(line, custom_fc_macros)) { continue; } struct fc_entry *entry = parse_fc_line(line); enum node_flavor flavor; if (entry == NULL) { flavor = NODE_ERROR; } else { flavor = NODE_FC_ENTRY; } union node_data nd; nd.fc_data = entry; if (insert_policy_node_next(cur, flavor, nd, lineno) != SELINT_SUCCESS) { free_policy_node(head); fclose(fd); return NULL; } cur = cur->next; free(line); line = NULL; buf_len = 0; } free(line); // getline alloc must be freed even if getline failed fclose(fd); return head; } selint-1.2.1/src/file_list.h0000644000175100001710000000245514167117255012660 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FILE_LIST_H #define FILE_LIST_H #include "tree.h" struct policy_file { char *filename; struct policy_node *ast; }; struct policy_file_node { struct policy_file *file; struct policy_file_node *next; }; struct policy_file_list { struct policy_file_node *head; struct policy_file_node *tail; }; void file_list_push_back(struct policy_file_list *list, struct policy_file *file); struct policy_file *make_policy_file(const char *filename, struct policy_node *ast); // Return 1 if filename matches the name of a file in list, and 0 otherwise int file_name_in_file_list(const char *filename, const struct policy_file_list *list); void free_file_list(struct policy_file_list *to_free); #endif selint-1.2.1/src/startup.h0000644000175100001710000000221714167117255012404 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef STARTUP_H #define STARTUP_H #include "selint_error.h" #include "file_list.h" enum selint_error load_access_vectors_kernel(const char *av_path); enum selint_error load_access_vectors_source(const char *av_path); void load_modules_normal(void); enum selint_error load_modules_source(const char *modules_conf_path); enum selint_error load_obj_perm_sets_source(const char *obj_perm_sets_path); enum selint_error load_devel_headers(struct policy_file_list *context_files); enum selint_error mark_transform_interfaces(const struct policy_file_list *files); #endif selint-1.2.1/src/util.h0000644000175100001710000000775314167117255011671 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef UTIL_H #define UTIL_H #include // ignore conversions discarding const specifier, e.g. // const char [] -> char * // const char *[2]' -> char *const * // necessary for calling fts_open() and initializing cfg_opt_t #ifdef __clang__ #define IGNORE_CONST_DISCARD_BEGIN _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wincompatible-pointer-types-discards-qualifiers\"") #define IGNORE_CONST_DISCARD_END _Pragma("clang diagnostic pop") #elif defined(__GNUC__) #define IGNORE_CONST_DISCARD_BEGIN _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wdiscarded-qualifiers\"") \ _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") #define IGNORE_CONST_DISCARD_END _Pragma("GCC diagnostic pop") #else #define IGNORE_CONST_DISCARD_BEGIN #define IGNORE_CONST_DISCARD_END #endif __attribute__((format(printf,1,2))) void print_if_verbose(const char *format, ...); /**************************************************** * Checks whether a string ends with a suffix. * str - The string to check. * str_len - The length of the string to check. * suffix - The suffix to check against. * suffix_len - The length of the suffix to check against. * Returns true if the string ends with the given suffi, else false. ****************************************************/ bool ends_with(const char *str, size_t str_len, const char *suffix, size_t suffix_len); /**************************************************** * Remove whitespaces of the end of a string. * str - The string to trim. * Return the passed and now trimed string. ****************************************************/ char* trim_right(char *str); /**************************************************** * * Conventions in refpolicy style policies * ****************************************************/ static const char *const RefPol_module_abbreviations[][2] = { { "fs" , "filesystem" }, { "corecmd" , "corecommands" }, { "seutil" , "selinuxutil" }, { "libs" , "libraries" }, { "dev" , "devices" }, { "term" , "terminal" }, { "corenet" , "corenetwork" }, { "auth" , "authlogin" }, { "userdom" , "userdomain" }, { "sysnet" , "sysnetwork" }, }; static const char *const RefPol_macros_with_module_prefix[] = { "domain_auto_transition_pattern", "domain_transition_pattern", }; /********************************** * Since the refpolicy style guide doesn't define what a "transform * interface" is, we use some heuristics. This checks if the interface * name ends with one of several strings used in interfaces that appear * to be what the style guide intends **********************************/ static const char *const RefPol_interface_transforming_suffixes[] = { "_type", "_file", "_domain", "_node", // Next three are found in mta module "_agent", "_delivery", "_sender", "_boolean", "_content", "_constrained", "_executable", "_exemption", "_object", "_mountpoint", }; static inline bool is_transform_interface(const char *if_name) { const char *suffix = strrchr(if_name, '_'); if (!suffix) { return false; } for (size_t i = 0; i < (sizeof RefPol_interface_transforming_suffixes / sizeof *RefPol_interface_transforming_suffixes); i++) { if (0 == strcmp(suffix, RefPol_interface_transforming_suffixes[i])) { return true; } } return false; } #endif selint-1.2.1/src/parse_functions.h0000644000175100001710000004113314167117255014104 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef PARSING_FUNCTIONS_H #define PARSING_FUNCTIONS_H #include "selint_error.h" #include "tree.h" #include "maps.h" /********************************** * insert_header * Add a header node at the next node in the tree, allocating all memory for it. * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated declaration node * module_name (in) - The name of the policy module * flavor (in) - The flavor being declared * lineno (in) - The line number * Returns - SELINT error code **********************************/ enum selint_error insert_header(struct policy_node **cur, const char *mn, enum header_flavor flavor, unsigned int lineno); /********************************** * Set the name of the current module to mn **********************************/ void set_current_module_name(const char *mn); /********************************** * Return the name of the current module * This is only available during parsing **********************************/ char *get_current_module_name(void); /********************************** * insert_comment * Add a comment node at the next node in the tree, allocating all memory for it. * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated declaration node * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error insert_comment(struct policy_node **cur, unsigned int lineno); /********************************** * insert_declaration * Add a declaration node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated declaration node * flavor (in)- What sort of declaration this is * name (in) - The name of the item being declared * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error insert_declaration(struct policy_node **cur, enum decl_flavor flavor, const char *name, struct string_list *attrs, unsigned int lineno); /********************************** * insert_aliases * Add alias nodes below the declaration and insert the aliases into the type map * cur (in) - The current spot in the tree. Will not be changed * aliases (in) - The aliases. This function will free the list * flavor (in) - The flavor being declared * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error insert_aliases(struct policy_node **cur, struct string_list *aliases, enum decl_flavor flavor, unsigned int lineno); /********************************** * insert_type_alias * Add a typealias rule node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated av rule node * type (in) - The name of the type in the node. * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error insert_type_alias(struct policy_node **cur, const char *type, unsigned int lineno); /********************************** * insert_av_rule * Add an av rule node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated av rule node * flavor (in) - What sort of av rule this is * sources (in) - (memory allocated by caller) the sources in the rule * targets (in) - (memory allocated by caller) the targets in the rule * object_classes (in) - (memory allocated by caller) the object classes in the rule * perms (in) - (memory allocated by caller) the perms in the rule * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error insert_av_rule(struct policy_node **cur, enum av_rule_flavor flavor, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, struct string_list *perms, unsigned int lineno); /********************************** * insert_xperm_av_rule * Add an extended permission av rule node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated av rule node * flavor (in) - What sort of av rule this is * sources (in) - (memory allocated by caller) the sources in the rule * targets (in) - (memory allocated by caller) the targets in the rule * object_classes (in) - (memory allocated by caller) the object classes in the rule * operation (in) - the operation implemented by this rule * perms (in) - (memory allocated by caller) the extended permission in the rule * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error insert_xperm_av_rule(struct policy_node **cur, enum av_rule_flavor flavor, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, const char *operation, struct string_list *perms, unsigned int lineno); /********************************** * insert_role_allow * Add a role allow node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated av rule node * from_role (in) - The role allowed to transition from * to_role (in) - The role allowed to transition to * lineno (in) - The line number of the rule * * Returns - SELINT error code **********************************/ enum selint_error insert_role_allow(struct policy_node **cur, struct string_list *from_roles, struct string_list *to_roles, unsigned int lineno); /********************************** * insert_role_types * Add a role types node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated av rule node * role (in) - The name of the role allowed to access types * types (in) - (memory allocated by caller) The types allowed to be accessed * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error insert_role_types(struct policy_node **cur, const char *role, struct string_list *types, unsigned int lineno); /********************************** * insert_type_transition * Add a type transition node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated type transition node * flavor (in) - The variety of type transition role. The normal case is type_transition (TT_TT), * but other options include type_member (TT_TM), type_change (TT_TC) and range_transition (TT_RT) * sources (in) - (memory allocated by caller) The sources in the rule * targets (in) - (memory allocated by caller) the targets in the rule * object_classes (in) - (memory allocated by caller) the object classes in the rule * default_type (in) - The type to transition to * name (in) - The name of the file for named transitions. Can be NULL if not specified. * lineno (in) - The line number of the rule * * Returns - SELINT error code **********************************/ enum selint_error insert_type_transition(struct policy_node **cur, enum tt_flavor flavor, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, const char *default_type, const char *name, unsigned int lineno); /********************************** * insert_role_transition * Add a role transition node at the next node in the tree, allocating all memory for it * cur (in, out) - The current spot in the tree. Will be updated to point to * the newly allocated role transition node * sources (in) - (memory allocated by caller) The sources in the rule * targets (in) - (memory allocated by caller) the targets in the rule * object_classes (in) - (memory allocated by caller) the object classes in the rule * default_role (in) - The role to transition to * lineno (in) - The line number of the rule * * Returns - SELINT error code **********************************/ enum selint_error insert_role_transition(struct policy_node **cur, struct string_list *sources, struct string_list *targets, struct string_list *object_classes, char *default_role, unsigned int lineno); enum selint_error insert_interface_call(struct policy_node **cur, const char *if_name, struct string_list *args, unsigned int lineno); enum selint_error insert_permissive_statement(struct policy_node **cur, const char *domain, unsigned int lineno); enum selint_error insert_semicolon(struct policy_node **cur, unsigned int lineno); enum selint_error insert_m4simplemacro(struct policy_node **cur, char *name, unsigned int lineno); /********************************** * begin_define * Add a define() node at the next node in the tree. Create its first child * as the start of the block. Set cur to the child node. Allocate all memory for * both nodes. * cur (in, out) - The current spot in the tree. Will be updated to point to the * first child of the define() node * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error begin_define(struct policy_node **cur, unsigned int lineno); /********************************** * end_define * Complete the define() block by moving cur back up to the parent level * cur (in, out) - The current spot in the tree. Will be updated to point to the * parent define() node * * Returns - SELINT error code **********************************/ enum selint_error end_define(struct policy_node **cur); /********************************** * begin_optional_policy * Add an optional policy node at the next node in the tree. Create its first child * as the start of the block. Set cur to the child node. Allocate all memory for * both nodes. * cur (in, out) - The current spot in the tree. Will be updated to point to the * first child of the optional_policy node * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error begin_optional_policy(struct policy_node **cur, unsigned int lineno); /********************************** * end_optional_policy * Complete the optional policy block by moving cur back up to the parent level * cur (in, out) - The current spot in the tree. Will be updated to point to the * parent optional policy node * * Returns - SELINT error code **********************************/ enum selint_error end_optional_policy(struct policy_node **cur); /********************************** * begin_optional_else * Add the else portion of an optional policy node at the next node in the tree. Create its first child * as the start of the block. Set cur to the child node. Allocate all memory for * both nodes. * cur (in, out) - The current spot in the tree. Will be updated to point to the * first child of the optional_policy node * lineno (in) - The line number * * Returns - SELINT error code **********************************/ enum selint_error begin_optional_else(struct policy_node **cur, unsigned int lineno); /********************************** * end_optional_policy * Complete the optional policy else block by moving cur back up to the parent level * cur (in, out) - The current spot in the tree. Will be updated to point to the * parent optional policy node * * Returns - SELINT error code **********************************/ enum selint_error end_optional_else(struct policy_node **cur); enum selint_error begin_tunable_policy(struct policy_node **cur, unsigned int lineno); enum selint_error end_tunable_policy(struct policy_node **cur); enum selint_error begin_boolean_policy(struct policy_node **cur, unsigned int lineno); enum selint_error end_boolean_policy(struct policy_node **cur); enum selint_error begin_interface_def(struct policy_node **cur, enum node_flavor flavor, const char *name, unsigned int lineno); enum selint_error end_interface_def(struct policy_node **cur); enum selint_error begin_gen_require(struct policy_node **cur, unsigned int lineno); enum selint_error end_gen_require(struct policy_node **cur, unsigned char unquoted); enum selint_error begin_require(struct policy_node **cur, unsigned int lineno); enum selint_error end_require(struct policy_node **cur); enum selint_error begin_ifdef(struct policy_node **cur, unsigned int lineno); enum selint_error end_ifdef(struct policy_node **cur); enum selint_error begin_ifelse(struct policy_node **cur, unsigned int lineno); enum selint_error end_ifelse(struct policy_node **cur); enum selint_error begin_m4_argument(struct policy_node **cur, unsigned int lineno); enum selint_error end_m4_argument(struct policy_node **cur); /********************************** * save_command * Save an selint control command in the tree. These go at the end of lines * and modify selint behavior while checking that line. * Current commands are: * - selint-disable:[check-id] * cur (in) - The current spot in the tree. Will be modified with information * about the command * comm (in) - What command string was in the comment * * Returns - SELint error code **********************************/ enum selint_error save_command(struct policy_node *cur, const char *comm); /********************************** * insert_type_attribute * Insert a type_attribute node into the tree * cur (in, out) - The current spot in the tree. Will be updated to point to the * new node. * type (in) - The type specified in the statement * attrs (in) - The attributes specified in the statement * lineno (in) - The line number * * Returns - SELint error code **********************************/ enum selint_error insert_type_attribute(struct policy_node **cur, const char *type, struct string_list *attrs, unsigned int lineno); /********************************** * insert_role_attribute * Insert a role_attribute node into the tree * cur (in, out) - The current spot in the tree. Will be updated to point to the * new node. * role (in) - The role specified in the statement * attrs (in) - The attributes specified in the statement * lineno (in) - The line number * * Returns - SELint error code **********************************/ enum selint_error insert_role_attribute(struct policy_node **cur, const char *role, struct string_list *attrs, unsigned int lineno); /********************************** * cleanup_parsing * Call after all parsing is done to free up memory **********************************/ void cleanup_parsing(void); #endif selint-1.2.1/src/parse_fc.h0000644000175100001710000000231714167117255012465 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef PARSE_FC_H #define PARSE_FC_H #include #include "tree.h" // Takes in a null terminated string that is an fc entry and populates an fc_entry struct struct fc_entry *parse_fc_line(char *line); struct sel_context *parse_context(char *context_str); // Return true if the line contains a defined custom fc macro, and false otherwise bool check_for_fc_macro(const char *line, const struct string_list *custom_fc_macros); // Parse an fc file and return a pointer to an abstract syntax tree representing the file struct policy_node *parse_fc_file(const char *filename, const struct string_list *custom_fc_macros); #endif selint-1.2.1/src/Makefile.in0000644000175100001710000006031214167117365012600 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = selint$(EXEEXT) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_selint_OBJECTS = main.$(OBJEXT) lex.$(OBJEXT) parse.$(OBJEXT) \ tree.$(OBJEXT) parse_functions.$(OBJEXT) maps.$(OBJEXT) \ runner.$(OBJEXT) parse_fc.$(OBJEXT) template.$(OBJEXT) \ file_list.$(OBJEXT) check_hooks.$(OBJEXT) fc_checks.$(OBJEXT) \ util.$(OBJEXT) if_checks.$(OBJEXT) selint_config.$(OBJEXT) \ string_list.$(OBJEXT) startup.$(OBJEXT) te_checks.$(OBJEXT) \ ordering.$(OBJEXT) color.$(OBJEXT) perm_macro.$(OBJEXT) selint_OBJECTS = $(am_selint_OBJECTS) selint_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/check_hooks.Po ./$(DEPDIR)/color.Po \ ./$(DEPDIR)/fc_checks.Po ./$(DEPDIR)/file_list.Po \ ./$(DEPDIR)/if_checks.Po ./$(DEPDIR)/lex.Po \ ./$(DEPDIR)/main.Po ./$(DEPDIR)/maps.Po \ ./$(DEPDIR)/ordering.Po ./$(DEPDIR)/parse.Po \ ./$(DEPDIR)/parse_fc.Po ./$(DEPDIR)/parse_functions.Po \ ./$(DEPDIR)/perm_macro.Po ./$(DEPDIR)/runner.Po \ ./$(DEPDIR)/selint_config.Po ./$(DEPDIR)/startup.Po \ ./$(DEPDIR)/string_list.Po ./$(DEPDIR)/te_checks.Po \ ./$(DEPDIR)/template.Po ./$(DEPDIR)/tree.Po \ ./$(DEPDIR)/util.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ -e s/c++$$/h++/ -e s/c$$/h/ YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) AM_V_YACC = $(am__v_YACC_@AM_V@) am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) am__v_YACC_0 = @echo " YACC " $@; am__v_YACC_1 = SOURCES = $(selint_SOURCES) DIST_SOURCES = $(selint_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/ylwrap lex.c parse.c parse.h DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ $(MAYBE_COVERAGE) \ -DSYSCONFDIR='"$(sysconfdir)"' AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_VALGRIND_drd = @ENABLE_VALGRIND_drd@ ENABLE_VALGRIND_helgrind = @ENABLE_VALGRIND_helgrind@ ENABLE_VALGRIND_memcheck = @ENABLE_VALGRIND_memcheck@ ENABLE_VALGRIND_sgcheck = @ENABLE_VALGRIND_sgcheck@ EXEEXT = @EXEEXT@ GREP = @GREP@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGES = @MANPAGES@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VALGRIND_ENABLED = @VALGRIND_ENABLED@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ valgrind_enabled_tools = @valgrind_enabled_tools@ valgrind_tools = @valgrind_tools@ selint_SOURCES = main.c lex.l parse.y tree.c tree.h selint_error.h parse_functions.c parse_functions.h maps.c maps.h runner.c runner.h parse_fc.c parse_fc.h template.c template.h file_list.c file_list.h check_hooks.c check_hooks.h fc_checks.c fc_checks.h util.c util.h if_checks.c if_checks.h selint_config.c selint_config.h string_list.c string_list.h startup.c startup.h te_checks.c te_checks.h ordering.c ordering.h color.c color.h perm_macro.c perm_macro.h BUILT_SOURCES = parse.h AM_YFLAGS = -d -Wno-yacc -Werror=conflicts-rr -Werror=conflicts-sr @COND_GCOV_TRUE@MAYBE_COVERAGE = --coverage -fno-inline -fno-inline-small-functions -fno-default-inline MOSTLYCLEANFILES = *.gcda *.gcno *.gcov lex.c parse.c parse.h all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .l .o .obj .y $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) parse.h: parse.c @if test ! -f $@; then rm -f parse.c; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) parse.c; else :; fi selint$(EXEEXT): $(selint_OBJECTS) $(selint_DEPENDENCIES) $(EXTRA_selint_DEPENDENCIES) @rm -f selint$(EXEEXT) $(AM_V_CCLD)$(LINK) $(selint_OBJECTS) $(selint_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_hooks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fc_checks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_list.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/if_checks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lex.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordering.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_fc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_functions.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perm_macro.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runner.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selint_config.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/startup.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_list.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/te_checks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/template.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .l.c: $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) .y.c: $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f lex.c -rm -f parse.c -rm -f parse.h -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/check_hooks.Po -rm -f ./$(DEPDIR)/color.Po -rm -f ./$(DEPDIR)/fc_checks.Po -rm -f ./$(DEPDIR)/file_list.Po -rm -f ./$(DEPDIR)/if_checks.Po -rm -f ./$(DEPDIR)/lex.Po -rm -f ./$(DEPDIR)/main.Po -rm -f ./$(DEPDIR)/maps.Po -rm -f ./$(DEPDIR)/ordering.Po -rm -f ./$(DEPDIR)/parse.Po -rm -f ./$(DEPDIR)/parse_fc.Po -rm -f ./$(DEPDIR)/parse_functions.Po -rm -f ./$(DEPDIR)/perm_macro.Po -rm -f ./$(DEPDIR)/runner.Po -rm -f ./$(DEPDIR)/selint_config.Po -rm -f ./$(DEPDIR)/startup.Po -rm -f ./$(DEPDIR)/string_list.Po -rm -f ./$(DEPDIR)/te_checks.Po -rm -f ./$(DEPDIR)/template.Po -rm -f ./$(DEPDIR)/tree.Po -rm -f ./$(DEPDIR)/util.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/check_hooks.Po -rm -f ./$(DEPDIR)/color.Po -rm -f ./$(DEPDIR)/fc_checks.Po -rm -f ./$(DEPDIR)/file_list.Po -rm -f ./$(DEPDIR)/if_checks.Po -rm -f ./$(DEPDIR)/lex.Po -rm -f ./$(DEPDIR)/main.Po -rm -f ./$(DEPDIR)/maps.Po -rm -f ./$(DEPDIR)/ordering.Po -rm -f ./$(DEPDIR)/parse.Po -rm -f ./$(DEPDIR)/parse_fc.Po -rm -f ./$(DEPDIR)/parse_functions.Po -rm -f ./$(DEPDIR)/perm_macro.Po -rm -f ./$(DEPDIR)/runner.Po -rm -f ./$(DEPDIR)/selint_config.Po -rm -f ./$(DEPDIR)/startup.Po -rm -f ./$(DEPDIR)/string_list.Po -rm -f ./$(DEPDIR)/te_checks.Po -rm -f ./$(DEPDIR)/template.Po -rm -f ./$(DEPDIR)/tree.Po -rm -f ./$(DEPDIR)/util.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: selint-1.2.1/src/maps.h0000644000175100001710000000614014167117255011641 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MAPS_H #define MAPS_H #include #include "tree.h" #include "selint_error.h" struct hash_elem { char *key; char *val; UT_hash_handle hh_type, hh_role, hh_user, hh_attr_type, hh_attr_role, hh_bool, hh_class, hh_perm, hh_mods, hh_ifs, hh_mod_layers; }; struct bool_hash_elem { char *key; int val; UT_hash_handle hh_transform, hh_filetrans, hh_role_if; }; struct sl_hash_elem { char *key; struct string_list *val; UT_hash_handle hh_permmacros; }; struct template_hash_elem { char *name; struct decl_list *declarations; struct if_call_list *calls; UT_hash_handle hh; }; void insert_into_decl_map(const char *name, const char *module_name, enum decl_flavor flavor); const char *look_up_in_decl_map(const char *name, enum decl_flavor flavor); void insert_into_mods_map(const char *mod_name, const char *status); const char *look_up_in_mods_map(const char *mod_name); void insert_into_mod_layers_map(const char *mod_name, const char *layer); const char *look_up_in_mod_layers_map(const char *mod_name); void insert_into_ifs_map(const char *if_name, const char *mod_name); const char *look_up_in_ifs_map(const char *if_name); void mark_transform_if(const char *if_name); int is_transform_if(const char *if_name); void mark_filetrans_if(const char *if_name); int is_filetrans_if(const char *if_name); void mark_role_if(const char *if_name); int is_role_if(const char *if_name); // Just generate a template entry in the map, but don't save any calls // or decls to it. This is helpful to know what is a template for certain // checks even if the template never calls or declares anything void insert_template_into_template_map(const char *name); void insert_decl_into_template_map(const char *name, enum decl_flavor flavor, const char *declaration); void insert_call_into_template_map(const char *name, struct if_call_data *call); const struct template_hash_elem *look_up_in_template_map(const char *name); const struct decl_list *look_up_decl_in_template_map(const char *name); const struct if_call_list *look_up_call_in_template_map(const char *name); void insert_into_permmacros_map(const char *name, struct string_list *permissions); const struct string_list *look_up_in_permmacros_map(const char *name); void visit_all_in_permmacros_map(void (*visitor)(const char *name, const struct string_list *permissions)); unsigned int permmacros_map_count(void); unsigned int decl_map_count(enum decl_flavor flavor); void free_all_maps(void); #endif selint-1.2.1/src/maps.c0000644000175100001710000003473614167117255011650 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "maps.h" #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ >= 4) #if (__clang_major__ >= 12) #define no_sanitize_unsigned_integer_ __attribute__((no_sanitize("unsigned-integer-overflow", "unsigned-shift-base"))) #else #define no_sanitize_unsigned_integer_ __attribute__((no_sanitize("unsigned-integer-overflow"))) #endif #else #define no_sanitize_unsigned_integer_ #endif static struct hash_elem *type_map = NULL; static struct hash_elem *role_map = NULL; static struct hash_elem *user_map = NULL; static struct hash_elem *attr_type_map = NULL; static struct hash_elem *attr_role_map = NULL; static struct hash_elem *bool_map = NULL; static struct hash_elem *class_map = NULL; static struct hash_elem *perm_map = NULL; static struct hash_elem *mods_map = NULL; static struct hash_elem *mod_layers_map = NULL; static struct hash_elem *ifs_map = NULL; static struct bool_hash_elem *transform_map = NULL; static struct bool_hash_elem *filetrans_map = NULL; static struct bool_hash_elem *role_if_map = NULL; static struct sl_hash_elem *permmacros_map = NULL; static struct template_hash_elem *template_map = NULL; no_sanitize_unsigned_integer_ static struct hash_elem *look_up_hash_elem(const char *name, enum decl_flavor flavor) { if (!name) { return NULL; } struct hash_elem *decl; switch (flavor) { case DECL_TYPE: HASH_FIND(hh_type, type_map, name, strlen(name), decl); break; case DECL_ROLE: HASH_FIND(hh_role, role_map, name, strlen(name), decl); break; case DECL_USER: HASH_FIND(hh_user, user_map, name, strlen(name), decl); break; case DECL_ATTRIBUTE: HASH_FIND(hh_attr_type, attr_type_map, name, strlen(name), decl); break; case DECL_ATTRIBUTE_ROLE: HASH_FIND(hh_attr_role, attr_role_map, name, strlen(name), decl); break; case DECL_BOOL: HASH_FIND(hh_bool, bool_map, name, strlen(name), decl); break; case DECL_CLASS: HASH_FIND(hh_class, class_map, name, strlen(name), decl); break; case DECL_PERM: HASH_FIND(hh_perm, perm_map, name, strlen(name), decl); break; default: decl = NULL; } return decl; } no_sanitize_unsigned_integer_ void insert_into_decl_map(const char *name, const char *module_name, enum decl_flavor flavor) { struct hash_elem *decl = look_up_hash_elem(name, flavor); if (decl == NULL) { // Item not in hash table already decl = malloc(sizeof(struct hash_elem)); decl->key = strdup(name); decl->val = strdup(module_name); switch (flavor) { case DECL_TYPE: HASH_ADD_KEYPTR(hh_type, type_map, decl->key, strlen(decl->key), decl); break; case DECL_ROLE: HASH_ADD_KEYPTR(hh_role, role_map, decl->key, strlen(decl->key), decl); break; case DECL_USER: HASH_ADD_KEYPTR(hh_user, user_map, decl->key, strlen(decl->key), decl); break; case DECL_ATTRIBUTE: HASH_ADD_KEYPTR(hh_attr_type, attr_type_map, decl->key, strlen(decl->key), decl); break; case DECL_ATTRIBUTE_ROLE: HASH_ADD_KEYPTR(hh_attr_role, attr_role_map, decl->key, strlen(decl->key), decl); break; case DECL_BOOL: HASH_ADD_KEYPTR(hh_bool, bool_map, decl->key, strlen(decl->key), decl); break; case DECL_CLASS: HASH_ADD_KEYPTR(hh_class, class_map, decl->key, strlen(decl->key), decl); break; case DECL_PERM: HASH_ADD_KEYPTR(hh_perm, perm_map, decl->key, strlen(decl->key), decl); break; default: free(decl->key); free(decl->val); free(decl); return; } } //TODO: else report error? } const char *look_up_in_decl_map(const char *name, enum decl_flavor flavor) { struct hash_elem *decl = look_up_hash_elem(name, flavor); if (decl == NULL) { return NULL; } else { return decl->val; } } no_sanitize_unsigned_integer_ void insert_into_mods_map(const char *mod_name, const char *status) { struct hash_elem *mod; HASH_FIND(hh_mods, mods_map, mod_name, strlen(mod_name), mod); if (!mod) { mod = malloc(sizeof(struct hash_elem)); mod->key = strdup(mod_name); mod->val = strdup(status); HASH_ADD_KEYPTR(hh_mods, mods_map, mod->key, strlen(mod->key), mod); } } no_sanitize_unsigned_integer_ const char *look_up_in_mods_map(const char *mod_name) { struct hash_elem *mod; HASH_FIND(hh_mods, mods_map, mod_name, strlen(mod_name), mod); if (mod == NULL) { return NULL; } else { return mod->val; } } no_sanitize_unsigned_integer_ void insert_into_mod_layers_map(const char *mod_name, const char *layer) { struct hash_elem *mod; HASH_FIND(hh_mod_layers, mod_layers_map, mod_name, strlen(mod_name), mod); if (!mod) { mod = malloc(sizeof(struct hash_elem)); mod->key = strdup(mod_name); mod->val = strdup(layer); HASH_ADD_KEYPTR(hh_mod_layers, mod_layers_map, mod->key, strlen(mod->key), mod); } } no_sanitize_unsigned_integer_ const char *look_up_in_mod_layers_map(const char *mod_name) { struct hash_elem *mod; HASH_FIND(hh_mod_layers, mod_layers_map, mod_name, strlen(mod_name), mod); if (mod == NULL) { return NULL; } else { return mod->val; } } no_sanitize_unsigned_integer_ void insert_into_ifs_map(const char *if_name, const char *mod_name) { struct hash_elem *if_call; HASH_FIND(hh_ifs, ifs_map, if_name, strlen(if_name), if_call); if (!if_call) { if_call = malloc(sizeof(struct hash_elem)); if_call->key = strdup(if_name); if_call->val = strdup(mod_name); HASH_ADD_KEYPTR(hh_ifs, ifs_map, if_call->key, strlen(if_call->key), if_call); } } no_sanitize_unsigned_integer_ const char *look_up_in_ifs_map(const char *if_name) { struct hash_elem *if_call; HASH_FIND(hh_ifs, ifs_map, if_name, strlen(if_name), if_call); if (if_call == NULL) { return NULL; } else { return if_call->val; } } unsigned int decl_map_count(enum decl_flavor flavor) { switch (flavor) { case DECL_TYPE: return HASH_CNT(hh_type, type_map); case DECL_ATTRIBUTE: return HASH_CNT(hh_attr_type, attr_type_map); case DECL_ATTRIBUTE_ROLE: return HASH_CNT(hh_attr_role, attr_role_map); case DECL_ROLE: return HASH_CNT(hh_role, role_map); case DECL_USER: return HASH_CNT(hh_user, user_map); case DECL_BOOL: return HASH_CNT(hh_bool, bool_map); case DECL_CLASS: return HASH_CNT(hh_class, class_map); case DECL_PERM: return HASH_CNT(hh_perm, perm_map); default: return 0; } } no_sanitize_unsigned_integer_ void mark_transform_if(const char *if_name) { struct bool_hash_elem *transform_if; HASH_FIND(hh_transform, transform_map, if_name, strlen(if_name), transform_if); if (!transform_if) { transform_if = malloc(sizeof(struct bool_hash_elem)); transform_if->key = strdup(if_name); transform_if->val = 1; HASH_ADD_KEYPTR(hh_transform, transform_map, transform_if->key, strlen(transform_if->key), transform_if); } else { transform_if->val = 1; } } no_sanitize_unsigned_integer_ int is_transform_if(const char *if_name) { struct bool_hash_elem *transform_if; HASH_FIND(hh_transform, transform_map, if_name, strlen(if_name), transform_if); if (transform_if && transform_if->val == 1) { return 1; } else { return 0; } } no_sanitize_unsigned_integer_ void mark_filetrans_if(const char *if_name) { struct bool_hash_elem *filetrans_if; HASH_FIND(hh_filetrans, filetrans_map, if_name, strlen(if_name), filetrans_if); if (!filetrans_if) { filetrans_if = malloc(sizeof(struct bool_hash_elem)); filetrans_if->key = strdup(if_name); filetrans_if->val = 1; HASH_ADD_KEYPTR(hh_filetrans, filetrans_map, filetrans_if->key, strlen(filetrans_if->key), filetrans_if); } else { filetrans_if->val = 1; } } no_sanitize_unsigned_integer_ int is_filetrans_if(const char *if_name) { struct bool_hash_elem *filetrans_if; HASH_FIND(hh_filetrans, filetrans_map, if_name, strlen(if_name), filetrans_if); if (filetrans_if && filetrans_if->val == 1) { return 1; } else { return 0; } } no_sanitize_unsigned_integer_ void mark_role_if(const char *if_name) { struct bool_hash_elem *role_if; HASH_FIND(hh_role_if, role_if_map, if_name, strlen(if_name), role_if); if (!role_if) { role_if = malloc(sizeof(struct bool_hash_elem)); role_if->key = strdup(if_name); role_if->val = 1; HASH_ADD_KEYPTR(hh_role_if, role_if_map, role_if->key, strlen(role_if->key), role_if); } else { role_if->val = 1; } } no_sanitize_unsigned_integer_ int is_role_if(const char *if_name) { struct bool_hash_elem *role_if; HASH_FIND(hh_role_if, role_if_map, if_name, strlen(if_name), role_if); if (role_if && role_if->val == 1) { return 1; } else { return 0; } } static void insert_decl(struct template_hash_elem *template, void *new_node) { if (template->declarations) { struct decl_list *cur = template->declarations; while (cur->next) { cur = cur->next; } cur->next = (struct decl_list *)new_node; } else { template->declarations = (struct decl_list *)new_node; } } static void insert_call(struct template_hash_elem *template, void *new_node) { if (template->calls) { struct if_call_list *cur = template->calls; while (cur->next) { cur = cur->next; } cur->next = (struct if_call_list *)new_node; } else { template->calls = (struct if_call_list *)new_node; } } static void insert_noop(__attribute__((unused)) struct template_hash_elem *template, __attribute__((unused)) void *new_node) { return; } no_sanitize_unsigned_integer_ static void insert_into_template_map(const char *name, void *new_node, void (*insertion_func)(struct template_hash_elem *, void *)) { struct template_hash_elem *template; HASH_FIND(hh, template_map, name, strlen(name), template); if (template == NULL) { template = malloc(sizeof(struct template_hash_elem)); template->name = strdup(name); template->declarations = NULL; template->calls = NULL; HASH_ADD_KEYPTR(hh, template_map, template->name, strlen(template->name), template); } insertion_func(template, new_node); } void insert_template_into_template_map(const char *name) { insert_into_template_map(name, NULL, insert_noop); } void insert_decl_into_template_map(const char *name, enum decl_flavor flavor, const char *declaration) { struct declaration_data *new_data = malloc(sizeof(struct declaration_data)); new_data->flavor = flavor; new_data->name = strdup(declaration); new_data->attrs = NULL; //Not needed struct decl_list *new_node = malloc(sizeof(struct decl_list)); new_node->decl = new_data; new_node->next = NULL; insert_into_template_map(name, new_node, insert_decl); } void insert_call_into_template_map(const char *name, struct if_call_data *call) { struct if_call_list *new_node = malloc(sizeof(struct if_call_list)); new_node->call = call; new_node->next = NULL; insert_into_template_map(name, new_node, insert_call); } no_sanitize_unsigned_integer_ const struct template_hash_elem *look_up_in_template_map(const char *name) { struct template_hash_elem *template; HASH_FIND(hh, template_map, name, strlen(name), template); return template; } const struct decl_list *look_up_decl_in_template_map(const char *name) { const struct template_hash_elem *template = look_up_in_template_map(name); if (template) { return template->declarations; } else { return NULL; } } const struct if_call_list *look_up_call_in_template_map(const char *name) { const struct template_hash_elem *template = look_up_in_template_map(name); if (template) { return template->calls; } else { return NULL; } } no_sanitize_unsigned_integer_ void insert_into_permmacros_map(const char *name, struct string_list *permissions) { struct sl_hash_elem *perm_macro; HASH_FIND(hh_permmacros, permmacros_map, name, strlen(name), perm_macro); if (!perm_macro) { perm_macro = malloc(sizeof(struct sl_hash_elem)); perm_macro->key = strdup(name); perm_macro->val = permissions; HASH_ADD_KEYPTR(hh_permmacros, permmacros_map, perm_macro->key, strlen(perm_macro->key), perm_macro); } } no_sanitize_unsigned_integer_ const struct string_list *look_up_in_permmacros_map(const char *name) { struct sl_hash_elem *perm_macro; HASH_FIND(hh_permmacros, permmacros_map, name, strlen(name), perm_macro); if (perm_macro == NULL) { return NULL; } else { return perm_macro->val; } } void visit_all_in_permmacros_map(void (*visitor)(const char *name, const struct string_list *permissions)) { const struct sl_hash_elem *cur_sl, *tmp_sl; HASH_ITER(hh_permmacros, permmacros_map, cur_sl, tmp_sl) { visitor(cur_sl->key, cur_sl->val); } } unsigned int permmacros_map_count() { return HASH_CNT(hh_permmacros, permmacros_map); } #define FREE_MAP(mn) HASH_ITER(hh_ ## mn, mn ## _map, cur_decl, tmp_decl) { \ HASH_DELETE(hh_ ## mn, mn ## _map, cur_decl); \ free(cur_decl->key); \ free(cur_decl->val); \ free(cur_decl); \ } \ #define FREE_BOOL_MAP(mn) HASH_ITER(hh_ ## mn, mn ## _map, cur_bool, tmp_bool) { \ HASH_DELETE(hh_ ## mn, mn ## _map, cur_bool); \ free(cur_bool->key); \ free(cur_bool); \ } \ void free_all_maps() { struct hash_elem *cur_decl, *tmp_decl; FREE_MAP(type); FREE_MAP(role); FREE_MAP(user); FREE_MAP(attr_type); FREE_MAP(attr_role); FREE_MAP(bool); FREE_MAP(class); FREE_MAP(perm); FREE_MAP(mods); FREE_MAP(mod_layers); FREE_MAP(ifs); struct bool_hash_elem *cur_bool, *tmp_bool; FREE_BOOL_MAP(transform); FREE_BOOL_MAP(filetrans); FREE_BOOL_MAP(role_if); struct sl_hash_elem *cur_sl, *tmp_sl; HASH_ITER(hh_permmacros, permmacros_map, cur_sl, tmp_sl) { HASH_DELETE(hh_permmacros, permmacros_map, cur_sl); free(cur_sl->key); free_string_list(cur_sl->val); free(cur_sl); } struct template_hash_elem *cur_template, *tmp_template; HASH_ITER(hh, template_map, cur_template, tmp_template) { HASH_DELETE(hh, template_map, cur_template); free(cur_template->name); free_decl_list(cur_template->declarations); free_if_call_list(cur_template->calls); free(cur_template); } } selint-1.2.1/src/template.c0000644000175100001710000001004214167117255012503 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include "template.h" #include "maps.h" char *replace_m4(const char *orig, const struct string_list *args) { size_t len_to_malloc = strlen(orig) + 1; const struct string_list *cur = args; while (cur) { len_to_malloc += strlen(cur->string); cur = cur->next; } // len_to_malloc is now overestimated, because the length of the original // arguments wasn't subtracted and not all args are necessarily substituted char *ret = malloc(len_to_malloc); *ret = '\0'; // If the string is only a substitution that there is no argument for, we need to be terminated const char *orig_pos = orig; char *ret_pos = ret; while (*orig_pos) { int arg_num; int after_num_pos; const char *dollar_pos = strchr(orig_pos, '$'); if (!dollar_pos) { strcpy(ret_pos, orig_pos); break; } strncpy(ret_pos, orig_pos, (size_t)(dollar_pos - orig_pos)); ret_pos += dollar_pos - orig_pos; orig_pos = dollar_pos; int ret_count = sscanf(orig_pos, "$%d%n", &arg_num, &after_num_pos); if (ret_count != 1) { // %n doesn't count for return of sscanf free(ret); return NULL; } orig_pos += after_num_pos; cur = args; while (cur && arg_num > 1) { cur = cur->next; arg_num--; } if (cur) { strcpy(ret_pos, cur->string); ret_pos += strlen(cur->string); } // Otherwise, we are inserting the empty string } return ret; } struct string_list *replace_m4_list(const struct string_list *replace_with, const struct string_list *replace_from) { struct string_list *ret = calloc(1, sizeof(struct string_list)); struct string_list *cur = ret; cur->string = replace_m4(replace_from->string, replace_with); cur->next = NULL; replace_from = replace_from->next; while (replace_from) { cur->next = calloc(1, sizeof(struct string_list)); cur = cur->next; cur->string = replace_m4(replace_from->string, replace_with); cur->next = NULL; replace_from = replace_from->next; } return ret; } enum selint_error add_template_declarations(const char *template_name, const struct string_list *args, struct string_list *parent_temp_names, const char *mod_name) { struct string_list *cur = parent_temp_names; while (cur) { if (strcmp(cur->string, template_name) == 0) { // Loop free_string_list(parent_temp_names); return SELINT_IF_CALL_LOOP; } cur = cur->next; } cur = calloc(1, sizeof(struct string_list)); cur->string = strdup(template_name); cur->next = parent_temp_names; const struct if_call_list *calls = look_up_call_in_template_map(template_name); while (calls) { struct string_list *new_args = replace_m4_list(args, calls->call->args); enum selint_error res = add_template_declarations(calls->call->name, new_args, cur, mod_name); free_string_list(new_args); if (res != SELINT_SUCCESS) { return res; } calls = calls->next; } const struct decl_list *decls = look_up_decl_in_template_map(template_name); while (decls) { char *new_decl = replace_m4(decls->decl->name, args); if (!new_decl) { free(cur->string); free(cur); return SELINT_M4_SUB_FAILURE; } insert_into_decl_map(new_decl, mod_name, decls->decl->flavor); free(new_decl); decls = decls->next; } free(cur->string); free(cur); return SELINT_SUCCESS; } selint-1.2.1/src/Makefile.am0000644000175100001710000000256014167117255012566 00000000000000# Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. bin_PROGRAMS = selint selint_SOURCES = main.c lex.l parse.y tree.c tree.h selint_error.h parse_functions.c parse_functions.h maps.c maps.h runner.c runner.h parse_fc.c parse_fc.h template.c template.h file_list.c file_list.h check_hooks.c check_hooks.h fc_checks.c fc_checks.h util.c util.h if_checks.c if_checks.h selint_config.c selint_config.h string_list.c string_list.h startup.c startup.h te_checks.c te_checks.h ordering.c ordering.h color.c color.h perm_macro.c perm_macro.h BUILT_SOURCES = parse.h AM_YFLAGS = -d -Wno-yacc -Werror=conflicts-rr -Werror=conflicts-sr if COND_GCOV MAYBE_COVERAGE=--coverage -fno-inline -fno-inline-small-functions -fno-default-inline endif AM_CFLAGS += $(MAYBE_COVERAGE) -DSYSCONFDIR='"$(sysconfdir)"' MOSTLYCLEANFILES = *.gcda *.gcno *.gcov lex.c parse.c parse.h selint-1.2.1/src/tree.c0000644000175100001710000003131714167117255011637 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "tree.h" #include "maps.h" #include "selint_error.h" enum selint_error insert_policy_node_child(struct policy_node *parent, enum node_flavor flavor, union node_data data, unsigned int lineno) { if (parent == NULL) { return SELINT_BAD_ARG; } struct policy_node *to_insert = malloc(sizeof(struct policy_node)); if (!to_insert) { return SELINT_OUT_OF_MEM; } to_insert->parent = parent; to_insert->next = NULL; to_insert->first_child = NULL; to_insert->flavor = flavor; to_insert->data = data; to_insert->exceptions = NULL; to_insert->lineno = lineno; if (parent->first_child == NULL) { parent->first_child = to_insert; to_insert->prev = NULL; } else { struct policy_node *cur = parent->first_child; while (cur->next != NULL) { cur = cur->next; } cur->next = to_insert; to_insert->prev = cur; } return SELINT_SUCCESS; } enum selint_error insert_policy_node_next(struct policy_node *prev, enum node_flavor flavor, union node_data data, unsigned int lineno) { if (prev == NULL) { return SELINT_BAD_ARG; } struct policy_node *to_insert = malloc(sizeof(struct policy_node)); if (!to_insert) { return SELINT_OUT_OF_MEM; } prev->next = to_insert; to_insert->parent = prev->parent; to_insert->next = NULL; to_insert->first_child = NULL; to_insert->flavor = flavor; to_insert->data = data; to_insert->prev = prev; to_insert->exceptions = NULL; to_insert->lineno = lineno; return SELINT_SUCCESS; } int is_template_call(const struct policy_node *node) { if (node == NULL || node->data.ic_data == NULL) { return 0; } if (node->flavor != NODE_IF_CALL) { return 0; } char *call_name = node->data.ic_data->name; if (look_up_in_template_map(call_name)) { return 1; } return 0; } const char *get_name_if_in_template(const struct policy_node *cur) { while (cur->parent) { cur = cur->parent; if (cur->flavor == NODE_TEMP_DEF) { return cur->data.str; } } return NULL; } const char *decl_flavor_to_string(enum decl_flavor flavor) { switch (flavor) { case DECL_TYPE: return "type"; case DECL_ATTRIBUTE: return "attribute"; case DECL_ATTRIBUTE_ROLE: return "attribute role"; case DECL_ROLE: return "role"; case DECL_USER: return "user"; case DECL_CLASS: return "class"; case DECL_PERM: return "permission"; case DECL_BOOL: return "boolean"; default: return "unknown"; } } struct string_list *get_names_in_node(const struct policy_node *node) { struct string_list *ret = NULL; struct string_list *cur = NULL; struct av_rule_data *av_data; struct type_transition_data *tt_data; struct role_transition_data *rt_data; struct declaration_data *d_data; struct if_call_data *ifc_data; struct role_allow_data *ra_data; struct role_types_data *rtyp_data; struct attribute_data *at_data; switch (node->flavor) { case NODE_AV_RULE: case NODE_XAV_RULE: // Since the common elements are ordered identically, we can just look // at the common subset for the XAV rule av_data = node->data.av_data; cur = ret = copy_string_list(av_data->sources); if (cur) { while (cur->next) { cur = cur->next; } cur->next = copy_string_list(av_data->targets); } else { ret = copy_string_list(av_data->targets); } break; case NODE_TT_RULE: tt_data = node->data.tt_data; cur = ret = copy_string_list(tt_data->sources); if (cur) { while (cur->next) { cur = cur->next; } cur->next = copy_string_list(tt_data->targets); } else { cur = ret = copy_string_list(tt_data->targets); } if (cur) { while (cur->next) { cur = cur->next; } cur->next = sl_from_str(tt_data->default_type); } else { cur = ret = sl_from_str(tt_data->default_type); } break; case NODE_RT_RULE: rt_data = node->data.rt_data; cur = ret = copy_string_list(rt_data->sources); if (cur) { while (cur->next) { cur = cur->next; } cur->next = copy_string_list(rt_data->targets); } else { cur = ret = copy_string_list(rt_data->targets); } if (cur) { while (cur->next) { cur = cur->next; } cur->next = sl_from_str(rt_data->default_role); } else { cur = ret = sl_from_str(rt_data->default_role); } break; case NODE_DECL: d_data = node->data.d_data; ret = sl_from_str(d_data->name); ret->next = copy_string_list(d_data->attrs); break; case NODE_IF_CALL: ifc_data = node->data.ic_data; ret = copy_string_list(ifc_data->args); break; case NODE_ROLE_ALLOW: ra_data = node->data.ra_data; cur = ret = copy_string_list(ra_data->from); while (cur->next) { cur = cur->next; } cur->next = copy_string_list(ra_data->to); break; case NODE_ROLE_TYPES: rtyp_data = node->data.rtyp_data; ret = sl_from_str(rtyp_data->role); ret->next = copy_string_list(rtyp_data->types); break; case NODE_TYPE_ATTRIBUTE: case NODE_ROLE_ATTRIBUTE: at_data = node->data.at_data; ret = sl_from_str(at_data->type); ret->next = copy_string_list(at_data->attrs); break; case NODE_ALIAS: case NODE_TYPE_ALIAS: case NODE_PERMISSIVE: ret = sl_from_str(node->data.str); break; /* NODE_TE_FILE, NODE_IF_FILE, NODE_FC_FILE, NODE_SPT_FILE, NODE_AV_FILE, NODE_HEADER, NODE_M4_CALL, NODE_M4_SIMPLE_MACRO, NODE_DEFINE, NODE_OPTIONAL_POLICY, NODE_OPTIONAL_ELSE, NODE_BOOLEAN_POLICY, NODE_TUNABLE_POLICY, NODE_IFDEF, NODE_IFELSE, NODE_M4_ARG, NODE_START_BLOCK, NODE_INTERFACE_DEF, NODE_TEMP_DEF, NODE_REQUIRE, NODE_GEN_REQ, NODE_FC_ENTRY, NODE_COMMENT, NODE_EMPTY, NODE_SEMICOLON, NODE_CLEANUP, NODE_ERROR */ default: break; } // Check if any of the types are exclusions cur = ret; while (cur) { if (cur->string[0] == '-') { // memmove is safe for overlapping strings // Length is strlen exactly because it doesn't copy the first // character, but does copy the null terminator memmove(cur->string, cur->string + 1, strlen(cur->string)); } cur = cur->next; } return ret; } struct string_list *get_names_required(const struct policy_node *node) { struct string_list *ret = NULL; struct string_list *ret_cursor = NULL; struct policy_node *cur = node->first_child; while (cur) { if (ret_cursor) { ret_cursor->next = get_names_in_node(cur); } else { ret = ret_cursor = get_names_in_node(cur); } while (ret_cursor && ret_cursor->next) { ret_cursor = ret_cursor->next; } cur = cur->next; } return ret; } int is_in_require(const struct policy_node *cur) { while (cur->parent) { cur = cur->parent; if (cur->flavor == NODE_GEN_REQ || cur->flavor == NODE_REQUIRE) { return 1; } } return 0; } struct policy_node *dfs_next(const struct policy_node *node) { if (node->first_child) { return node->first_child; } else if (node->next) { return node->next; } else { while (node->parent && !node->parent->next) { node = node->parent; } if (node->parent) { return node->parent->next; } else { return NULL; } } } enum selint_error free_policy_node(struct policy_node *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } switch (to_free->flavor) { case NODE_HEADER: free_header_data(to_free->data.h_data); break; case NODE_AV_RULE: free_av_rule_data(to_free->data.av_data); break; case NODE_XAV_RULE: free_xav_rule_data(to_free->data.xav_data); break; case NODE_ROLE_ALLOW: free_ra_data(to_free->data.ra_data); break; case NODE_ROLE_TYPES: free_rtyp_data(to_free->data.rtyp_data); break; case NODE_TT_RULE: free_type_transition_data(to_free->data.tt_data); break; case NODE_RT_RULE: free_role_transition_data(to_free->data.rt_data); break; case NODE_IF_CALL: free_if_call_data(to_free->data.ic_data); break; case NODE_DECL: free_declaration_data(to_free->data.d_data); break; case NODE_FC_ENTRY: free_fc_entry(to_free->data.fc_data); break; case NODE_TYPE_ATTRIBUTE: case NODE_ROLE_ATTRIBUTE: free_attribute_data(to_free->data.at_data); break; case NODE_GEN_REQ: free_gen_require_data(to_free->data.gr_data); break; default: if (to_free->data.str != NULL) { free(to_free->data.str); } break; } free(to_free->exceptions); to_free->exceptions = NULL; free_policy_node(to_free->first_child); to_free->first_child = NULL; free_policy_node(to_free->next); to_free->next = NULL; to_free->prev = NULL; free(to_free); return SELINT_SUCCESS; } enum selint_error free_header_data(struct header_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free(to_free->module_name); free(to_free); return SELINT_SUCCESS; } enum selint_error free_av_rule_data(struct av_rule_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free_string_list(to_free->sources); free_string_list(to_free->targets); free_string_list(to_free->object_classes); free_string_list(to_free->perms); free(to_free); return SELINT_SUCCESS; } enum selint_error free_xav_rule_data(struct xav_rule_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free_string_list(to_free->sources); free_string_list(to_free->targets); free_string_list(to_free->object_classes); free(to_free->operation); free_string_list(to_free->perms); free(to_free); return SELINT_SUCCESS; } enum selint_error free_ra_data(struct role_allow_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free_string_list(to_free->from); free_string_list(to_free->to); free(to_free); return SELINT_SUCCESS; } enum selint_error free_rtyp_data(struct role_types_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free(to_free->role); free_string_list(to_free->types); free(to_free); return SELINT_SUCCESS; } enum selint_error free_type_transition_data(struct type_transition_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free_string_list(to_free->sources); free_string_list(to_free->targets); free_string_list(to_free->object_classes); free(to_free->default_type); free(to_free->name); free(to_free); return SELINT_SUCCESS; } enum selint_error free_role_transition_data(struct role_transition_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free_string_list(to_free->sources); free_string_list(to_free->targets); free_string_list(to_free->object_classes); free(to_free->default_role); free(to_free); return SELINT_SUCCESS; } enum selint_error free_if_call_data(struct if_call_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free(to_free->name); free_string_list(to_free->args); free(to_free); return SELINT_SUCCESS; } enum selint_error free_declaration_data(struct declaration_data *to_free) { if (to_free == NULL) { return SELINT_BAD_ARG; } free_string_list(to_free->attrs); free(to_free->name); free(to_free); return SELINT_SUCCESS; } enum selint_error free_decl_list(struct decl_list *to_free) { while (to_free) { free_declaration_data(to_free->decl); struct decl_list *tmp = to_free; to_free = to_free->next; free(tmp); } return SELINT_SUCCESS; } // The if call data structs in an if call list are pointers to data that is freed elsewhere enum selint_error free_if_call_list(struct if_call_list *to_free) { while (to_free) { struct if_call_list *tmp = to_free; to_free = to_free->next; free(tmp); } return SELINT_SUCCESS; } void free_fc_entry(struct fc_entry *to_free) { if (to_free->path) { free(to_free->path); } if (to_free->context) { free_sel_context(to_free->context); } free(to_free); } void free_sel_context(struct sel_context *to_free) { if (to_free->user) { free(to_free->user); } if (to_free->role) { free(to_free->role); } if (to_free->type) { free(to_free->type); } if (to_free->range) { free(to_free->range); } free(to_free); } void free_attribute_data(struct attribute_data *to_free) { if (to_free->type) { free(to_free->type); } if (to_free->attrs) { free_string_list(to_free->attrs); } free(to_free); } void free_gen_require_data(struct gen_require_data *to_free) { free(to_free); } selint-1.2.1/aclocal.m40000644000175100001710000016721314167117364011613 00000000000000# generated automatically by aclocal 1.16.1 -*- Autoconf -*- # Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html # =========================================================================== # # SYNOPSIS # # AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off) # AX_VALGRIND_CHECK() # # DESCRIPTION # # AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows # running `make check` under a variety of Valgrind tools to check for # memory and threading errors. # # Defines VALGRIND_CHECK_RULES which should be substituted in your # Makefile; and $enable_valgrind which can be used in subsequent configure # output. VALGRIND_ENABLED is defined and substituted, and corresponds to # the value of the --enable-valgrind option, which defaults to being # enabled if Valgrind is installed and disabled otherwise. Individual # Valgrind tools can be disabled via --disable-valgrind-, the # default is configurable via the AX_VALGRIND_DFLT command or is to use # all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT # calls must be made before the call to AX_VALGRIND_CHECK. # # If unit tests are written using a shell script and automake's # LOG_COMPILER system, the $(VALGRIND) variable can be used within the # shell scripts to enable Valgrind, as described here: # # https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html # # Usage example: # # configure.ac: # # AX_VALGRIND_DFLT([sgcheck], [off]) # AX_VALGRIND_CHECK # # in each Makefile.am with tests: # # @VALGRIND_CHECK_RULES@ # VALGRIND_SUPPRESSIONS_FILES = my-project.supp # EXTRA_DIST = my-project.supp # # This results in a "check-valgrind" rule being added. Running `make # check-valgrind` in that directory will recursively run the module's test # suite (`make check`) once for each of the available Valgrind tools (out # of memcheck, helgrind and drd) while the sgcheck will be skipped unless # enabled again on the commandline with --enable-valgrind-sgcheck. The # results for each check will be output to test-suite-$toolname.log. The # target will succeed if there are zero errors and fail otherwise. # # Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in # memcheck, helgrind, drd and sgcheck. These are useful because often only # some of those tools can be ran cleanly on a codebase. # # The macro supports running with and without libtool. # # LICENSE # # Copyright (c) 2014, 2015, 2016 Philip Withnall # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 17 dnl Configured tools m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]]) m4_set_add_all([valgrind_exp_tool_set], [sgcheck]) m4_foreach([vgtool], [valgrind_tool_list], [m4_define([en_dflt_valgrind_]vgtool, [on])]) AC_DEFUN([AX_VALGRIND_DFLT],[ m4_define([en_dflt_valgrind_$1], [$2]) ])dnl AM_EXTRA_RECURSIVE_TARGETS([check-valgrind]) m4_foreach([vgtool], [valgrind_tool_list], [AM_EXTRA_RECURSIVE_TARGETS([check-valgrind-]vgtool)]) AC_DEFUN([AX_VALGRIND_CHECK],[ dnl Check for --enable-valgrind AC_ARG_ENABLE([valgrind], [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])], [enable_valgrind=$enableval],[enable_valgrind=]) AS_IF([test "$enable_valgrind" != "no"],[ # Check for Valgrind. AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind]) AS_IF([test "$VALGRIND" = ""],[ AS_IF([test "$enable_valgrind" = "yes"],[ AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind]) ],[ enable_valgrind=no ]) ],[ enable_valgrind=yes ]) ]) AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind]) # Check for Valgrind tools we care about. [valgrind_enabled_tools=] m4_foreach([vgtool],[valgrind_tool_list],[ AC_ARG_ENABLE([valgrind-]vgtool, m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl [AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl [AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]), [enable_valgrind_]vgtool[=$enableval], [enable_valgrind_]vgtool[=]) AS_IF([test "$enable_valgrind" = "no"],[ enable_valgrind_]vgtool[=no], [test "$enable_valgrind_]vgtool[" ]dnl m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[ AC_CACHE_CHECK([for Valgrind tool ]vgtool, [ax_cv_valgrind_tool_]vgtool,[ ax_cv_valgrind_tool_]vgtool[=no m4_set_contains([valgrind_exp_tool_set],vgtool, [m4_define([vgtoolx],[exp-]vgtool)], [m4_define([vgtoolx],vgtool)]) AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[ ax_cv_valgrind_tool_]vgtool[=yes ]) ]) AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[ AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool) ],[ enable_valgrind_]vgtool[=no ]) ],[ enable_valgrind_]vgtool[=yes ]) ]) AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])[" ]) AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool) ]) AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["]) AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools]) [VALGRIND_CHECK_RULES=' # Valgrind check # # Optional: # - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions # files to load. (Default: empty) # - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. # (Default: --num-callers=30) # - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: # memcheck, helgrind, drd, sgcheck). (Default: various) # Optional variables VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) VALGRIND_FLAGS ?= --num-callers=30 VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no VALGRIND_helgrind_FLAGS ?= --history-level=approx VALGRIND_drd_FLAGS ?= VALGRIND_sgcheck_FLAGS ?= # Internal use valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) valgrind_quiet = $(valgrind_quiet_$(V)) valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) valgrind_quiet_0 = --quiet valgrind_v_use = $(valgrind_v_use_$(V)) valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY)) valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%-am,%,$''@):; # Support running with and without libtool. ifneq ($(LIBTOOL),) valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute else valgrind_lt = endif # Use recursive makes in order to ignore errors during check check-valgrind-am: ifeq ($(VALGRIND_ENABLED),yes) $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k \ $(foreach tool, $(valgrind_enabled_tools), check-valgrind-$(tool)) else @echo "Need to reconfigure with --enable-valgrind" endif # Valgrind running VALGRIND_TESTS_ENVIRONMENT = \ $(TESTS_ENVIRONMENT) \ env VALGRIND=$(VALGRIND) \ G_SLICE=always-malloc,debug-blocks \ G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly VALGRIND_LOG_COMPILER = \ $(valgrind_lt) \ $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) define valgrind_tool_rule check-valgrind-$(1)-am: ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes) ifneq ($$(TESTS),) $$(valgrind_v_use)$$(MAKE) check-TESTS \ TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \ LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \ LOG_FLAGS="$$(valgrind_$(1)_flags)" \ TEST_SUITE_LOG=test-suite-$(1).log endif else ifeq ($$(VALGRIND_ENABLED),yes) @echo "Need to reconfigure with --enable-valgrind-$(1)" else @echo "Need to reconfigure with --enable-valgrind" endif endef $(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool)))) A''M_DISTCHECK_CONFIGURE_FLAGS ?= A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind MOSTLYCLEANFILES ?= MOSTLYCLEANFILES += $(valgrind_log_files) .PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools)) '] AC_SUBST([VALGRIND_CHECK_RULES]) m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])]) ]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR # Copyright (C) 2002-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. Try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR selint-1.2.1/test-driver0000755000175100001710000001104214167117365012136 00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2018 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: selint-1.2.1/depcomp0000755000175100001710000005602014167117365011322 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: selint-1.2.1/README0000644000175100001710000001377714167117255010637 00000000000000SUMMARY SELint is a program to perform static code analysis on SELinux policy source files INSTALLING FROM TAR DOWNLOAD To install from a downloaded tarball, first install the following dependencies: On rpm based distros: uthash-devel libconfuse libconfuse-devel check check-devel On apt based distros: uthash-dev libconfuse-dev check Then run: ./configure make make install INSTALLING FROM GIT If you are building from a git repo checkout, you'll also need bison, flex, autotools (automake, autoconf, aclocal, autoreconf) and the autoconf-archive package. Then you can run ./autogen.sh to set up autotools and then follow the steps above. USAGE selint [OPTIONS] FILE [...] OPTIONS -c CONFIGFILE, --config=CONFIGFILE Override default config with config specified on command line. See CONFIGURATION section for config file syntax. --color=COLOR_OPTION Configure color output. Options are on, off and auto (the default). --context=CONTEXT_PATH Also parse any .te or .if files found in CONTEXT_PATH and load symbols associated with them for use when checking the policy files to be analyzed. No checks are run on these files. Implies -s. --debug-parser Enable debug output for the internal policy parser. Very noisy, useful to debug parsing failures. -d CHECKID, --disable=CHECKID Disable check with the given ID. -e CHECKID, --enable=CHECKID Enable check with the given ID. -E, --only-enabled Only run checks that are explicitly enabled with the --enable option. -F, --fail Exit with a non-zero value if any issue was found. -h, --help Show help menu about command line options. -l LEVEL, --level=LEVEL Only list errors with a severity level at or greater than LEVEL. Options are C (convention), S (style), W (warning), E (error), F (fatal error). See SEVERITY LEVELS for more information. If this option is not specified, SELint will default to the level selected in the applicable config file. --scan-hidden-dirs Scan hidden directories. By default hidden directories (like '.git') are skipped in recursive mode. -s, --source Run in "source mode" to scan a policy source repository that is designed to compile into a full system policy. If this flag is not specified, SELint will assume that scanned policy files are intended to be loaded into the currently running system policy. -S, --summary Display a summary of issues found after running the analysis. --summary-only Only display a summary of issues found after running the analysis. Do not show the individual findings. Implies -S. -r, --recursive Scan recursively and check all SELinux policy files found. -v, --verbose Enable verbose output -V, --version Show version information and exit. CONFIGURATION A global configuration is specified at the install prefix supplied to ./configure (typically /usr/local/etc). This can be overridden on the command line using the -c option. Options specified on the command line override options from the config file. See the global config file for details on config file syntax. SEVERITY LEVELS SELint messages are assocatied with a severity level, indicating the significance of the issue. Available levels are listed below in increasing order of significance. C (convention) - A violation of common style conventions S (style) - Stylistic "code smell" that may be associated with unintended behavior W (warning) - Non standard policy that may result in issues such as run time errors or security issues E (error) - Important issues that may result in errors at compile time or run time F (fatal error) - Error that prevents further processing SELINT EXCEPTIONS To eliminate one or more checks on one line, add a comment containing a string in any of the following formats: * "selint-disable:E-003" * "selint-disable: E-003" * "selint-disable:E-003,E-004" * "selint-disable: E-003, E-004" This is currently only supported in te and if files OUTPUT SELint outputs messages in the following format: [filename]:[lineno]: ([SEVERITY LEVEL]): [MESSAGE] ([ISSUE ID]) For example: example.te:127: (E) Interface from module not in optional_policy block (E-001) CHECK IDS The following checks may be performed: C-001: Violation of refpolicy te file ordering conventions C-004: Interface does not have documentation comment C-005: Permissions in av rule or class declaration not ordered C-006: Declarations in require block not ordered C-007: Redudant type specification instead of self keyword S-001: Require block used instead of interface call S-002: File context file labels with type not declared in module S-003: Unnecessary semicolon S-004: Template call from an interface S-005: Declaration in interface S-006: Bare module statement S-007: Call to gen_context omits mls component S-008: Unquoted gen_require block S-009: Permission macro suffix does not match class name S-010: Permission macro usage suggested W-001: Type or attribute referenced without explicit declaration W-002: Type, attribute or role used but not listed in require block in interface W-003: Unused type, attribute or role listed in require block W-004: Potentially unescaped regex character in file contexts paths W-005: Interface call from module not in optional_policy block W-006: Interface call with empty argument W-007: Unquoted space in argument of interface call W-008: Allow rule with complement or wildcard permission W-009: Module name does not match file name W-010: Call to unknown interface W-011: Declaration in require block not defined in own module E-002: Bad file context format E-003: Nonexistent user listed in fc file E-004: Nonexistent role listed in fc file E-005: Nonexistent type listed in fc file E-006: Declaration and interface with same name E-007: Usage of unknown permission or permission macro E-008: Usage of unknown class E-009: Empty optional or require macro block E-010: Usage of unknown simple m4 macro or stray word F-001: Policy syntax error prevents further processing F-002: Internal error in SELint selint-1.2.1/check_examples.txt0000644000175100001710000000416614167117255013463 00000000000000 Here are examples of errors that will cause each possible result: Convention: C-001: type foo_t; allow foo_t self:process signal; type bar_t; C-004: interface(`foo_read_conf',` ... ') C-005: allow foo_t bar_t:file { write read }; C-006: gen_require(` type foo_t, bar_t; class foobar; ') C-007: allow myapp_t myapp_t:process signal; Style: S-001: require { type foo_t; } S-003: foo(bar); S-004: template(`bar',`') interface(`foo',` bar() ') S-005: interface(`foo',` type foo_t; ') S-006: module foo 1.0; S-007: gen_context(system_u:object_r:foo_t) S-008: gen_require( type foo_t; ) S-009: allow foo_t bar_t:file read_fifo_file_perms; S-010: allow foo_t bar_t:file { open read }; Warning: W-001: # etc_t is defined in files module read_files_pattern(foo_t, etc_t, etc_t) W-002: interface(`foo_read_conf',` read_files_pattern($1, foo_conf_t, foo_conf_t) ') W-003: interface(`foo_read_conf',` gen_require(` type foo_conf_t; ') ') W-004: /path/with/unescaped.dot -- gen_context(system_u:object_r:foo_exec_t,s0) W-005: # foo is set to module in modules.conf foo_read_conf() W-006: foo() W-007: foo(bar baz) W-008: allow foo_t bar_t:file *; W-009: #In foo.te policy_module(bar, 1.0) W-010: init_this-if-does-not-exist(bar_t) W-011: interface(`foo_read_conf',` gen_require(` type this_type_does_not_exist; # type from different module type bar_conf_t; ') ') Error: E-002: /usr/bin/foo -- gen_erquire(system_u:object_r:foo_exec_t, s0) E-003: /usr/bin/foo -- gen_require(not_a_valid_user:object_r:foo_exec_t, s0) E-004: /usr/bin/foo -- gen_require(system_u:not_a_valid_role:foo_exec_t, s0) E-004: /usr/bin/foo -- gen_require(system_u:object_r:not_a_valid_type, s0) E-005: # There is no type named foo_exce_t defined in our policy /usr/bin/foo -- gen_require(system_u:object_r:foo_exce_t, s0) E-006: attribute foo; interface(`foo',`') E-007: allow foo_t bar_t:file reed_file_perms; E-008: allow foo_t bar_t:File read_file_perms; E-009: optional_policy(` #do_something(type_t) ') E-010: bare_m4_macro selint-1.2.1/configure.ac0000644000175100001710000000564714167117255012242 00000000000000# Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([selint], [1.2.1], [Daniel.Burgener@microsoft.com]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([subdir-objects]) # Checks for programs. AC_PROG_CC AC_PROG_CC_STDC AC_PROG_LEX AC_PROG_YACC # Check for testsuite Check library AC_ARG_WITH([check], [AS_HELP_STRING([--without-check], [Build without testsuite depending on Check (default: Build with testsuite)])], [with_check=${withval}], [with_check=yes]) AM_CONDITIONAL([WITH_CHECK], [test "x$with_check" = "xyes"]) AS_IF([test "x$with_check" = "xyes"], [PKG_CHECK_MODULES([CHECK], [check >= 0.11.0], [], [AC_MSG_ERROR([Check not found])])]) # Checks for libraries. AC_SEARCH_LIBS([cfg_init], [confuse], [], [ AC_MSG_ERROR([Unable to find libconfuse]) ]) # Checks for header files. AC_FUNC_ALLOCA AC_CHECK_HEADERS([inttypes.h libintl.h malloc.h stddef.h stdlib.h string.h unistd.h stdbool.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_INT8_T AC_TYPE_SIZE_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT8_T # Checks for library functions. AC_CHECK_FUNCS([memset strdup]) AC_ARG_ENABLE([gcov], [AS_HELP_STRING([--enable-gcov], [use Gcov to test the test suite])], [enable_gcov=${enableval}], []) AM_CONDITIONAL([COND_GCOV],[ test "x$enable_gcov" "=" "xyes" ]) AC_CHECK_PROGS([HELP2MAN], [help2man]) if ! test -z "$HELP2MAN" then AC_SUBST(MANPAGES, selint.1) HAVE_HELP2MAN=true fi AM_CONDITIONAL([HAVE_HELP2MAN], [test "x$HAVE_HELP2MAN" "=" "xtrue"]) AX_VALGRIND_DFLT([drd], [off]) AX_VALGRIND_DFLT([helgrind], [off]) AX_VALGRIND_DFLT([sgcheck], [off]) AX_VALGRIND_CHECK AC_CHECK_HEADER([uthash.h], [], [AC_MSG_ERROR([Unable to find uthash header])]) AM_CFLAGS="-Wall -Wextra -Wcast-qual -Wconversion -Wmissing-format-attribute -Wmissing-noreturn -Wmissing-prototypes -Wpointer-arith -Wshadow -Wstrict-prototypes -Wundef -Wunused -Wwrite-strings" AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], [Treat compiler warnings as errors (default: Do not treat as errors)])], [AM_CFLAGS+=" -Werror"]) AC_SUBST([AM_CFLAGS]) AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile man/Makefile]) AC_OUTPUT() selint-1.2.1/LICENSE0000644000175100001710000002613614167117255010755 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. selint-1.2.1/configure0000755000175100001710000064662114167117364011667 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for selint 1.2.1. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: Daniel.Burgener@microsoft.com about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='selint' PACKAGE_TARNAME='selint' PACKAGE_VERSION='1.2.1' PACKAGE_STRING='selint 1.2.1' PACKAGE_BUGREPORT='Daniel.Burgener@microsoft.com' PACKAGE_URL='' ac_unique_file="src" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS AM_CFLAGS VALGRIND_CHECK_RULES valgrind_enabled_tools valgrind_tools ENABLE_VALGRIND_sgcheck ENABLE_VALGRIND_drd ENABLE_VALGRIND_helgrind ENABLE_VALGRIND_memcheck VALGRIND_ENABLED VALGRIND_ENABLED_FALSE VALGRIND_ENABLED_TRUE VALGRIND HAVE_HELP2MAN_FALSE HAVE_HELP2MAN_TRUE MANPAGES HELP2MAN COND_GCOV_FALSE COND_GCOV_TRUE ALLOCA EGREP GREP CPP CHECK_LIBS CHECK_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG WITH_CHECK_FALSE WITH_CHECK_TRUE YFLAGS YACC LEXLIB LEX_OUTPUT_ROOT LEX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking with_check enable_gcov enable_valgrind enable_valgrind_memcheck enable_valgrind_helgrind enable_valgrind_drd enable_valgrind_sgcheck enable_werror ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS YACC YFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR CHECK_CFLAGS CHECK_LIBS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures selint 1.2.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/selint] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of selint 1.2.1:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-gcov use Gcov to test the test suite --enable-valgrind Whether to enable Valgrind on the unit tests --disable-valgrind-memcheck Whether to skip memcheck during the Valgrind tests --enable-valgrind-helgrind Whether to use helgrind during the Valgrind tests --enable-valgrind-drd Whether to use drd during the Valgrind tests --enable-valgrind-sgcheck Whether to use sgcheck during the Valgrind tests --enable-werror Treat compiler warnings as errors (default: Do not treat as errors) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-check Build without testsuite depending on Check (default: Build with testsuite) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory YACC The `Yet Another Compiler Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path CHECK_CFLAGS C compiler flags for CHECK, overriding pkg-config CHECK_LIBS linker flags for CHECK, overriding pkg-config CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF selint configure 1.2.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## -------------------------------------------- ## ## Report this to Daniel.Burgener@microsoft.com ## ## -------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_find_intX_t LINENO BITS VAR # ----------------------------------- # Finds a signed integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_intX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in int$2_t 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else case $ac_type in #( int$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_intX_t # ac_fn_c_find_uintX_t LINENO BITS VAR # ------------------------------------ # Finds an unsigned integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_uintX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 $as_echo_n "checking for uint$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : case $ac_type in #( uint$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_uintX_t cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by selint $as_me 1.2.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" am__api_version='1.16' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='selint' VERSION='1.2.1' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # Checks for programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 $as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 $as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi case $ac_cv_prog_cc_stdc in #( no) : ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if ${ac_cv_prog_cc_c99+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 else ac_cv_prog_cc_stdc=no fi fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 $as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } if ${ac_cv_prog_cc_stdc+:} false; then : $as_echo_n "(cached) " >&6 fi case $ac_cv_prog_cc_stdc in #( no) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; #( '') : { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 $as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; esac for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ yyless ((input () != 0)); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" # Check for testsuite Check library # Check whether --with-check was given. if test "${with_check+set}" = set; then : withval=$with_check; with_check=${withval} else with_check=yes fi if test "x$with_check" = "xyes"; then WITH_CHECK_TRUE= WITH_CHECK_FALSE='#' else WITH_CHECK_TRUE='#' WITH_CHECK_FALSE= fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi if test "x$with_check" = "xyes"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CHECK" >&5 $as_echo_n "checking for CHECK... " >&6; } if test -n "$CHECK_CFLAGS"; then pkg_cv_CHECK_CFLAGS="$CHECK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"check >= 0.11.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "check >= 0.11.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CHECK_CFLAGS=`$PKG_CONFIG --cflags "check >= 0.11.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$CHECK_LIBS"; then pkg_cv_CHECK_LIBS="$CHECK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"check >= 0.11.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "check >= 0.11.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CHECK_LIBS=`$PKG_CONFIG --libs "check >= 0.11.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then CHECK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "check >= 0.11.0" 2>&1` else CHECK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "check >= 0.11.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$CHECK_PKG_ERRORS" >&5 as_fn_error $? "Check not found" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Check not found" "$LINENO" 5 else CHECK_CFLAGS=$pkg_cv_CHECK_CFLAGS CHECK_LIBS=$pkg_cv_CHECK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi fi # Checks for libraries. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing cfg_init" >&5 $as_echo_n "checking for library containing cfg_init... " >&6; } if ${ac_cv_search_cfg_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cfg_init (); int main () { return cfg_init (); ; return 0; } _ACEOF for ac_lib in '' confuse; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_cfg_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_cfg_init+:} false; then : break fi done if ${ac_cv_search_cfg_init+:} false; then : else ac_cv_search_cfg_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_cfg_init" >&5 $as_echo "$ac_cv_search_cfg_init" >&6; } ac_res=$ac_cv_search_cfg_init if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else as_fn_error $? "Unable to find libconfuse" "$LINENO" 5 fi # Checks for header files. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi for ac_header in inttypes.h libintl.h malloc.h stddef.h stdlib.h string.h unistd.h stdbool.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Checks for typedefs, structures, and compiler characteristics. ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" case $ac_cv_c_int16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int16_t $ac_cv_c_int16_t _ACEOF ;; esac ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" case $ac_cv_c_int32_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int32_t $ac_cv_c_int32_t _ACEOF ;; esac ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t" case $ac_cv_c_int8_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int8_t $ac_cv_c_int8_t _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" case $ac_cv_c_uint16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define uint16_t $ac_cv_c_uint16_t _ACEOF ;; esac ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" case $ac_cv_c_uint32_t in #( no|yes) ;; #( *) $as_echo "#define _UINT32_T 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define uint32_t $ac_cv_c_uint32_t _ACEOF ;; esac ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" case $ac_cv_c_uint8_t in #( no|yes) ;; #( *) $as_echo "#define _UINT8_T 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define uint8_t $ac_cv_c_uint8_t _ACEOF ;; esac # Checks for library functions. for ac_func in memset strdup do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # Check whether --enable-gcov was given. if test "${enable_gcov+set}" = set; then : enableval=$enable_gcov; enable_gcov=${enableval} fi if test "x$enable_gcov" "=" "xyes" ; then COND_GCOV_TRUE= COND_GCOV_FALSE='#' else COND_GCOV_TRUE='#' COND_GCOV_FALSE= fi for ac_prog in help2man do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HELP2MAN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HELP2MAN"; then ac_cv_prog_HELP2MAN="$HELP2MAN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HELP2MAN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi HELP2MAN=$ac_cv_prog_HELP2MAN if test -n "$HELP2MAN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HELP2MAN" >&5 $as_echo "$HELP2MAN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$HELP2MAN" && break done if ! test -z "$HELP2MAN" then MANPAGES=selint.1 HAVE_HELP2MAN=true fi if test "x$HAVE_HELP2MAN" "=" "xtrue"; then HAVE_HELP2MAN_TRUE= HAVE_HELP2MAN_FALSE='#' else HAVE_HELP2MAN_TRUE='#' HAVE_HELP2MAN_FALSE= fi # Check whether --enable-valgrind was given. if test "${enable_valgrind+set}" = set; then : enableval=$enable_valgrind; enable_valgrind=$enableval else enable_valgrind= fi if test "$enable_valgrind" != "no"; then : # Check for Valgrind. # Extract the first word of "valgrind", so it can be a program name with args. set dummy valgrind; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_VALGRIND+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$VALGRIND"; then ac_cv_prog_VALGRIND="$VALGRIND" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_VALGRIND="valgrind" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi VALGRIND=$ac_cv_prog_VALGRIND if test -n "$VALGRIND"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VALGRIND" >&5 $as_echo "$VALGRIND" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$VALGRIND" = ""; then : if test "$enable_valgrind" = "yes"; then : as_fn_error $? "Could not find valgrind; either install it or reconfigure with --disable-valgrind" "$LINENO" 5 else enable_valgrind=no fi else enable_valgrind=yes fi fi if test "$enable_valgrind" = "yes"; then VALGRIND_ENABLED_TRUE= VALGRIND_ENABLED_FALSE='#' else VALGRIND_ENABLED_TRUE='#' VALGRIND_ENABLED_FALSE= fi VALGRIND_ENABLED=$enable_valgrind # Check for Valgrind tools we care about. valgrind_enabled_tools= # Check whether --enable-valgrind-memcheck was given. if test "${enable_valgrind_memcheck+set}" = set; then : enableval=$enable_valgrind_memcheck; enable_valgrind_memcheck=$enableval else enable_valgrind_memcheck= fi if test "$enable_valgrind" = "no"; then : enable_valgrind_memcheck=no elif test "$enable_valgrind_memcheck" != "no"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Valgrind tool memcheck" >&5 $as_echo_n "checking for Valgrind tool memcheck... " >&6; } if ${ax_cv_valgrind_tool_memcheck+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_valgrind_tool_memcheck=no if `$VALGRIND --tool=memcheck --help >/dev/null 2>&1`; then : ax_cv_valgrind_tool_memcheck=yes fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_valgrind_tool_memcheck" >&5 $as_echo "$ax_cv_valgrind_tool_memcheck" >&6; } if test "$ax_cv_valgrind_tool_memcheck" = "no"; then : if test "$enable_valgrind_memcheck" = "yes"; then : as_fn_error $? "Valgrind does not support memcheck; reconfigure with --disable-valgrind-memcheck" "$LINENO" 5 else enable_valgrind_memcheck=no fi else enable_valgrind_memcheck=yes fi fi if test "$enable_valgrind_memcheck" = "yes"; then : valgrind_enabled_tools="$valgrind_enabled_tools memcheck" fi ENABLE_VALGRIND_memcheck=$enable_valgrind_memcheck # Check whether --enable-valgrind-helgrind was given. if test "${enable_valgrind_helgrind+set}" = set; then : enableval=$enable_valgrind_helgrind; enable_valgrind_helgrind=$enableval else enable_valgrind_helgrind= fi if test "$enable_valgrind" = "no"; then : enable_valgrind_helgrind=no elif test "$enable_valgrind_helgrind" = "yes"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Valgrind tool helgrind" >&5 $as_echo_n "checking for Valgrind tool helgrind... " >&6; } if ${ax_cv_valgrind_tool_helgrind+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_valgrind_tool_helgrind=no if `$VALGRIND --tool=helgrind --help >/dev/null 2>&1`; then : ax_cv_valgrind_tool_helgrind=yes fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_valgrind_tool_helgrind" >&5 $as_echo "$ax_cv_valgrind_tool_helgrind" >&6; } if test "$ax_cv_valgrind_tool_helgrind" = "no"; then : if test "$enable_valgrind_helgrind" = "yes"; then : as_fn_error $? "Valgrind does not support helgrind; reconfigure with --disable-valgrind-helgrind" "$LINENO" 5 else enable_valgrind_helgrind=no fi else enable_valgrind_helgrind=yes fi fi if test "$enable_valgrind_helgrind" = "yes"; then : valgrind_enabled_tools="$valgrind_enabled_tools helgrind" fi ENABLE_VALGRIND_helgrind=$enable_valgrind_helgrind # Check whether --enable-valgrind-drd was given. if test "${enable_valgrind_drd+set}" = set; then : enableval=$enable_valgrind_drd; enable_valgrind_drd=$enableval else enable_valgrind_drd= fi if test "$enable_valgrind" = "no"; then : enable_valgrind_drd=no elif test "$enable_valgrind_drd" = "yes"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Valgrind tool drd" >&5 $as_echo_n "checking for Valgrind tool drd... " >&6; } if ${ax_cv_valgrind_tool_drd+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_valgrind_tool_drd=no if `$VALGRIND --tool=drd --help >/dev/null 2>&1`; then : ax_cv_valgrind_tool_drd=yes fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_valgrind_tool_drd" >&5 $as_echo "$ax_cv_valgrind_tool_drd" >&6; } if test "$ax_cv_valgrind_tool_drd" = "no"; then : if test "$enable_valgrind_drd" = "yes"; then : as_fn_error $? "Valgrind does not support drd; reconfigure with --disable-valgrind-drd" "$LINENO" 5 else enable_valgrind_drd=no fi else enable_valgrind_drd=yes fi fi if test "$enable_valgrind_drd" = "yes"; then : valgrind_enabled_tools="$valgrind_enabled_tools drd" fi ENABLE_VALGRIND_drd=$enable_valgrind_drd # Check whether --enable-valgrind-sgcheck was given. if test "${enable_valgrind_sgcheck+set}" = set; then : enableval=$enable_valgrind_sgcheck; enable_valgrind_sgcheck=$enableval else enable_valgrind_sgcheck= fi if test "$enable_valgrind" = "no"; then : enable_valgrind_sgcheck=no elif test "$enable_valgrind_sgcheck" = "yes"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Valgrind tool sgcheck" >&5 $as_echo_n "checking for Valgrind tool sgcheck... " >&6; } if ${ax_cv_valgrind_tool_sgcheck+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_valgrind_tool_sgcheck=no if `$VALGRIND --tool=exp-sgcheck --help >/dev/null 2>&1`; then : ax_cv_valgrind_tool_sgcheck=yes fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_valgrind_tool_sgcheck" >&5 $as_echo "$ax_cv_valgrind_tool_sgcheck" >&6; } if test "$ax_cv_valgrind_tool_sgcheck" = "no"; then : if test "$enable_valgrind_sgcheck" = "yes"; then : as_fn_error $? "Valgrind does not support sgcheck; reconfigure with --disable-valgrind-sgcheck" "$LINENO" 5 else enable_valgrind_sgcheck=no fi else enable_valgrind_sgcheck=yes fi fi if test "$enable_valgrind_sgcheck" = "yes"; then : valgrind_enabled_tools="$valgrind_enabled_tools sgcheck" fi ENABLE_VALGRIND_sgcheck=$enable_valgrind_sgcheck valgrind_tools="memcheck helgrind drd sgcheck" valgrind_enabled_tools=$valgrind_enabled_tools VALGRIND_CHECK_RULES=' # Valgrind check # # Optional: # - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions # files to load. (Default: empty) # - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. # (Default: --num-callers=30) # - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: # memcheck, helgrind, drd, sgcheck). (Default: various) # Optional variables VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) VALGRIND_FLAGS ?= --num-callers=30 VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no VALGRIND_helgrind_FLAGS ?= --history-level=approx VALGRIND_drd_FLAGS ?= VALGRIND_sgcheck_FLAGS ?= # Internal use valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) valgrind_quiet = $(valgrind_quiet_$(V)) valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) valgrind_quiet_0 = --quiet valgrind_v_use = $(valgrind_v_use_$(V)) valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY)) valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%-am,%,$''@):; # Support running with and without libtool. ifneq ($(LIBTOOL),) valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute else valgrind_lt = endif # Use recursive makes in order to ignore errors during check check-valgrind-am: ifeq ($(VALGRIND_ENABLED),yes) $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k \ $(foreach tool, $(valgrind_enabled_tools), check-valgrind-$(tool)) else @echo "Need to reconfigure with --enable-valgrind" endif # Valgrind running VALGRIND_TESTS_ENVIRONMENT = \ $(TESTS_ENVIRONMENT) \ env VALGRIND=$(VALGRIND) \ G_SLICE=always-malloc,debug-blocks \ G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly VALGRIND_LOG_COMPILER = \ $(valgrind_lt) \ $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) define valgrind_tool_rule check-valgrind-$(1)-am: ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes) ifneq ($$(TESTS),) $$(valgrind_v_use)$$(MAKE) check-TESTS \ TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \ LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \ LOG_FLAGS="$$(valgrind_$(1)_flags)" \ TEST_SUITE_LOG=test-suite-$(1).log endif else ifeq ($$(VALGRIND_ENABLED),yes) @echo "Need to reconfigure with --enable-valgrind-$(1)" else @echo "Need to reconfigure with --enable-valgrind" endif endef $(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool)))) A''M_DISTCHECK_CONFIGURE_FLAGS ?= A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind MOSTLYCLEANFILES ?= MOSTLYCLEANFILES += $(valgrind_log_files) .PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools)) ' ac_fn_c_check_header_mongrel "$LINENO" "uthash.h" "ac_cv_header_uthash_h" "$ac_includes_default" if test "x$ac_cv_header_uthash_h" = xyes; then : else as_fn_error $? "Unable to find uthash header" "$LINENO" 5 fi AM_CFLAGS="-Wall -Wextra -Wcast-qual -Wconversion -Wmissing-format-attribute -Wmissing-noreturn -Wmissing-prototypes -Wpointer-arith -Wshadow -Wstrict-prototypes -Wundef -Wunused -Wwrite-strings" # Check whether --enable-werror was given. if test "${enable_werror+set}" = set; then : enableval=$enable_werror; AM_CFLAGS+=" -Werror" fi ac_config_files="$ac_config_files Makefile src/Makefile tests/Makefile man/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_CHECK_TRUE}" && test -z "${WITH_CHECK_FALSE}"; then as_fn_error $? "conditional \"WITH_CHECK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${COND_GCOV_TRUE}" && test -z "${COND_GCOV_FALSE}"; then as_fn_error $? "conditional \"COND_GCOV\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_HELP2MAN_TRUE}" && test -z "${HAVE_HELP2MAN_FALSE}"; then as_fn_error $? "conditional \"HAVE_HELP2MAN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${VALGRIND_ENABLED_TRUE}" && test -z "${VALGRIND_ENABLED_FALSE}"; then as_fn_error $? "conditional \"VALGRIND_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by selint $as_me 1.2.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ selint config.status 1.2.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. Try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi selint-1.2.1/man/0000755000175100001710000000000014167117420010565 500000000000000selint-1.2.1/man/selint.10000644000175100001710000000500614167117373012075 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. .TH SELINT "1" "January 2022" "SELint 1.2.1" "User Commands" .SH NAME SELint \- Perform static source code analysis on SELinux policy source files .SH SYNOPSIS .B selint [\fI\,OPTIONS\/\fR] \fI\,FILE \/\fR[...] .SH DESCRIPTION Perform static code analysis on SELinux policy source. .TP \fB\-c\fR, \fB\-\-config\fR=\fI\,CONFIGFILE\/\fR Override default config with config specified on command line. See CONFIGURATION section for config file syntax. .TP \fB\-\-color\fR=\fI\,COLOR_OPTION\/\fR Configure color output. Options are on, off and auto (the default). .TP \fB\-\-context\fR=\fI\,CONTEXT_PATH\/\fR Recursively scan CONTEXT_PATH to find additional te and if files to parse, but not scan. SELint will assume the scanned policy files are intended to be compiled together with the context files. are intended to be compiled together with the context files. Implies \fB\-s\fR. .TP \fB\-\-debug\-parser\fR Enable debug output for the internal policy parser. Very noisy, useful to debug parsing failures. .TP \fB\-d\fR, \fB\-\-disable\fR=\fI\,CHECKID\/\fR Disable check with the given ID. .TP \fB\-e\fR, \fB\-\-enable\fR=\fI\,CHECKID\/\fR Enable check with the given ID. .TP \fB\-E\fR, \fB\-\-only\-enabled\fR Only run checks that are explicitly enabled with the \fB\-\-enable\fR option. .TP \fB\-F\fR, \fB\-\-fail\fR Exit with a non\-zero value if any issue was found. .TP \fB\-h\fR, \fB\-\-help\fR Display this menu. .TP \fB\-l\fR, \fB\-\-level\fR=\fI\,LEVEL\/\fR Only list errors with a severity level at or greater than LEVEL. Options are C (convention), S (style), W (warning), E (error), F (fatal error). .TP \fB\-\-scan\-hidden\-dirs\fR Scan hidden directories. By default hidden directories (like '.git') are skipped in recursive mode. .TP \fB\-s\fR, \fB\-\-source\fR Run in "source mode" to scan a policy source repository that is designed to compile into a full system policy. .TP \fB\-S\fR, \fB\-\-summary\fR Display a summary of issues found after running the analysis. .TP \fB\-\-summary\-only\fR Only display a summary of issues found after running the analysis. Do not show the individual findings. Implies \fB\-S\fR. .TP \fB\-r\fR, \fB\-\-recursive\fR Scan recursively and check all SELinux policy files found. .TP \fB\-v\fR, \fB\-\-verbose\fR Enable verbose output. .TP \fB\-V\fR, \fB\-\-version\fR Show version information and exit. .SH REPORTING_BUGS Report bugs at https://github.com/TresysTechnology/selint/issues .SH AUTHOR Daniel Burgener selint-1.2.1/man/selint.h2m0000644000175100001710000000021414167117255012416 00000000000000[AUTHOR] Daniel Burgener [REPORTING_BUGS] Report bugs at https://github.com/TresysTechnology/selint/issues selint-1.2.1/man/Makefile.in0000644000175100001710000004271514167117365012573 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = man ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man1_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_VALGRIND_drd = @ENABLE_VALGRIND_drd@ ENABLE_VALGRIND_helgrind = @ENABLE_VALGRIND_helgrind@ ENABLE_VALGRIND_memcheck = @ENABLE_VALGRIND_memcheck@ ENABLE_VALGRIND_sgcheck = @ENABLE_VALGRIND_sgcheck@ EXEEXT = @EXEEXT@ GREP = @GREP@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGES = @MANPAGES@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VALGRIND_ENABLED = @VALGRIND_ENABLED@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ valgrind_enabled_tools = @valgrind_enabled_tools@ valgrind_tools = @valgrind_tools@ SOURCES = selint.h2m @HAVE_HELP2MAN_TRUE@man1_MANS = $(MANPAGES) @HAVE_HELP2MAN_FALSE@EXTRA_DIST = $(SOURCES) @HAVE_HELP2MAN_TRUE@EXTRA_DIST = $(man1_MANS) $(SOURCES) @HAVE_HELP2MAN_TRUE@CLEANFILES = $(MANPAGES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu man/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man1: $(man1_MANS) @$(NORMAL_INSTALL) @list1='$(man1_MANS)'; \ list2=''; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ tags-am uninstall uninstall-am uninstall-man uninstall-man1 .PRECIOUS: Makefile @HAVE_HELP2MAN_TRUE@selint.1: ../src/main.c $(SOURCES) @HAVE_HELP2MAN_TRUE@ $(HELP2MAN) -n "Perform static source code analysis on SELinux policy source files" -N -i selint.h2m -o $@ ../src/selint # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: selint-1.2.1/man/Makefile.am0000644000175100001710000000157614167117255012560 00000000000000# Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. SOURCES=selint.h2m if HAVE_HELP2MAN man1_MANS=$(MANPAGES) EXTRA_DIST=$(man1_MANS) $(SOURCES) CLEANFILES=$(MANPAGES) selint.1: ../src/main.c $(SOURCES) $(HELP2MAN) -n "Perform static source code analysis on SELinux policy source files" -N -i selint.h2m -o $@ ../src/selint else EXTRA_DIST=$(SOURCES) endif selint-1.2.1/ylwrap0000755000175100001710000001531414167117365011212 00000000000000#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2018 Free Software Foundation, Inc. # # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . get_dirname () { case $1 in */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; # Otherwise, we want the empty string (not "."). esac } # guard FILE # ---------- # The CPP macro used to guard inclusion of FILE. guard () { printf '%s\n' "$1" \ | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ -e 's/__*/_/g' } # quote_for_sed [STRING] # ---------------------- # Return STRING (or stdin) quoted to be used as a sed pattern. quote_for_sed () { case $# in 0) cat;; 1) printf '%s\n' "$1";; esac \ | sed -e 's|[][\\.*]|\\&|g' } case "$1" in '') echo "$0: No files given. Try '$0 --help' for more information." 1>&2 exit 1 ;; --basedir) basedir=$2 shift 2 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . EOF exit $? ;; -v|--v*) echo "ylwrap $scriptversion" exit $? ;; esac # The input. input=$1 shift # We'll later need for a correct munging of "#line" directives. input_sub_rx=`get_dirname "$input" | quote_for_sed` case $input in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input=`pwd`/$input ;; esac input_rx=`get_dirname "$input" | quote_for_sed` # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot=false if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot=true fi # The parser itself, the first file, is the destination of the .y.c # rule in the Makefile. parser=$1 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for # instance, we rename #include "y.tab.h" into #include "parse.h" # during the conversion from y.tab.c to parse.c. sed_fix_filenames= # Also rename header guards, as Bison 2.7 for instance uses its header # guard in its implementation file. sed_fix_header_guards= while test $# -ne 0; do if test x"$1" = x"--"; then shift break fi from=$1 # Handle y_tab.c and y_tab.h output by DOS if $y_tab_nodot; then case $from in "y.tab.c") from=y_tab.c;; "y.tab.h") from=y_tab.h;; esac fi shift to=$1 shift sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" done # The program to run. prog=$1 shift # Make any relative path in $prog absolute. case $prog in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog=`pwd`/$prog ;; esac dirname=ylwrap$$ do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 mkdir $dirname || exit 1 cd $dirname case $# in 0) "$prog" "$input" ;; *) "$prog" "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then for from in * do to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend '../'. case $to in [\\/]* | ?:[\\/]*) target=$to;; *) target=../$to;; esac # Do not overwrite unchanged header files to avoid useless # recompilations. Always update the parser itself: it is the # destination of the .y.c rule in the Makefile. Divert the # output of all other files to a temporary file so we can # compare them to existing versions. if test $from != $parser; then realtarget=$target target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` fi # Munge "#line" or "#" directives. Don't let the resulting # debug information point at an absolute srcdir. Use the real # output file name, not yy.lex.c for instance. Adjust the # include guards too. sed -e "/^#/!b" \ -e "s|$input_rx|$input_sub_rx|" \ -e "$sed_fix_filenames" \ -e "$sed_fix_header_guards" \ "$from" >"$target" || ret=$? # Check whether files must be updated. if test "$from" != "$parser"; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$to is unchanged" rm -f "$target" else echo "updating $to" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the parser. This is a # blatant hack to let us support using "yacc -d". If -d is not # specified, don't fail when the header file is "missing". if test "$from" = "$parser"; then ret=1 fi fi done fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: selint-1.2.1/CHANGELOG0000644000175100001710000001001114167117255011143 00000000000000# SELint Changelog ## [1.2.1] 2022-01-10 ### Changed - Checks referencing attributes now see attributes assigned to a type as part of a type declaration ### Fixed - Various parser fixes and enhancements - Support IVv4 address embedding ## [1.2.0] 2021-01-18 ### Added (general features) - New ./configure option --enable-werror to compile treating errors as warnings. - Parse errors now display info about exactly where in the line the failure occurred - spec file for building on rpm based distros ### Added (checks) - C-006 for unordered declarations in require blocks - C-007 for missing use of the self keyword - E-009 for empty optional and require blocks - E-010 for stray bare words ### Changed - New C-001 ordering option refpolicy-light (see sample selint.conf for details) - Extend S-009 to support multi-class av rules - Improved error messages for various error cases - selint-disable now allows a space before check ids - You can now use multiple --context arguments ### Fixed - Support object class specifications in role transitions - Lots of cleanup and fixes for C-001 ordering checks - Support extended permission class av rules (allowxperm etc) - Internal cleanup and improvements - Allow multiple roles in role allow statements ## [1.1.0] 2020-05-19 ### Added (general features) - -S flag to print a summary of issue found following an analysis - --context flag to specify additional files to parse but not scan. This is primarily helpful if you want to only scan your modified files in a full source repository. (If you are planning on loading your local modules into your already installed policy and have local development headers in a standard location, selint should find them by default and you don't need to use this option) - -F flag to return an error code on issues found - --summary-only flag to output a summary of issues found without displaying the actual issues - ./configure flag to disable unit testing. This can be used on systems with older versions of libcheck. - Colored output ### Added (checks) - C-005 for permission ordering - S-003 for unneeded semicolons - S-004 for template calls from interfaces - S-005 for declarations in an interface - S-006 for the use of a bare module statement instead of policy_module() macro - S-007 for the use of a gen_context() macro with no mls component specified - S-008 for gen_require() macro calls with unquoted arguments - S-009 for permission macros that don't match object class - S-010 suggestiong usage of permission macros - W-006 for interface call with empty arguments - W-007 for unexpected spaces in interface arguments - W-008 for permission lists with * or ~ - W-009 for module name not matching file name - E-006 for declaration/interface name clash - E-007 for usage of unknown permission macros ### Changed - Turn C-001 off by default. - Assume the presence of system_u user and object_r role if no config is loaded. - SELint will no longer scan file_contexts file that are probably generated by the build system. This behavior can be turned off by setting skip_checking_generated_fcs=false in the config - W-001 and W-002 check additional types of rules ### Fixed - Man page generation in distribution tarballs now works after make clean - documentation cleanup - Various parser fixes - Clean up of check C-001 ## [1.0.2] - 2020-01-30 ### Fixed - (Issue #11) Include CHANGELOG, LICENSE and testing input files in release tarballs ## [1.0.1] - 2020-01-28 ### Added - Warning for invalid check ids in config or on command line - CI for github pushes - Enabled many warnings in build system - Changelog ### Fixed - Check W-002 now handles multiple requires in the same interface correctly - (Issue #2) Handle types prefixed with "-" correctly in checks - Handle type aliases correctly in checks W-002 and W-003 - Fix double free in certain parse error corner cases - Look at role transitions in relevant checks (C-001, W-002, W-003) - Fix false positives on W-004 when a regex character is in square brackets - General Code Cleanup ## [1.0.0] - 2020-01-15 Initial Release selint-1.2.1/selint.conf0000644000175100001710000000700414167117255012106 00000000000000# This is the configuration file for SELint. The global configuration file # is the default if no other configuration is provided, but can be overridden # by user specific and project specific confgurations, or a configuration file # can be provided on the command line. # Set the severity level to report. Options are "convention", "style", # "warning", "error" and "fatal". SELint will report all errors at or above # the selected level severity = "convention" # Check enabling works as follows each step may override the one prior: # 1. All checks at or above the set severity level are enabled by default # 2. Checks may be disabled using the "disable" option below # 3. Checks may be enabled in either normal or source modes using the "enable_normal" and "enable_source" options below # 4. Checks may be disabled on the command line using the -d option # 5. Checks may be enabled on the command line using the -e option # Uncomment and modify to disable selected checks. This can be overridden on # the command line disable = { C-001, C-006, W-010, W-011, E-003, E-004 } # enable description #enable_normal = { S-002, E-002 } enable_source = { W-010, W-011, E-003, E-004 } # Modules.conf location. If you are running SELint in "source mode", you need # to supply a modules.conf file in order to run all checks. SELint will look # in the default location of policy/modules.conf from the directory where it # is run. To use a different path specify it here. #modules_conf_path = policy/modules.conf # Users and roles are often not declared in te files like other policy # constructs. Use the below options to specify valid users and roles that # SELint should not report as invalid even if they are not found in the # policy assume_users = { system_u } assume_roles = { object_r } # If you have defined any custom macros for use in fc files, list them here, # otherwise, SELint will report E-002 on occurrences of them # custom_fc_macros = { } # If you have defined any custom simple macros for use in te and if files, list them here, # otherwise, SELint will report E-010 on occurrences of them # custom_te_simple_macros = { } # What ordering standard you would like to apply when running check C-001 # Options are: # - refpolicy: Follow the refpolicy Style Guide (https://github.com/SELinuxProject/refpolicy/wiki/StyleGuide) # - refpolicy-light: Similar to refpolicy, but do not distinct base interface calls (except kernel module) # - refpolicy-lax: (default) Similar to refpolicy, but ignore interface # and block ordering requirements. ordering_rules = "refpolicy-lax" # What ordering in require blocks you would like to apply when running check C-006 # The following six flavors must each be used exactly once: # attribute, attribute_role, bool, class, role, type # If unset, this defaults to the following order: #ordering_requires = { bool, role, attribute_role, attribute, type, class } ordering_requires = { bool, attribute, attribute_role, type, class, role } # Whether to check the order (alphabetically) of requires of the same flavor when running check C-006 # If unset, this defaults to true. ordering_requires_same_flavor = false # Whether to ignore known false-positives on generated policy files. # In recursive mode SELint checks all files with known endings, regardless # if they are source or build generated files, like base.fc . # Currently the following checks are going to be disabled on build generated # files: # S-002: base.fc, all_mods.fc, $MODNAME.mod.fc # If unset, this defaults to true. #skip_checking_generated_fcs = true selint-1.2.1/config.h.in0000644000175100001710000001027714167117364011773 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the header file. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT32_T /* Define for Solaris 2.5.1 so the uint8_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT8_T /* Define to the type of a signed integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef int16_t /* Define to the type of a signed integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef int32_t /* Define to the type of a signed integer type of width exactly 8 bits if such a type exists and the standard includes do not define it. */ #undef int8_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to the type of an unsigned integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef uint16_t /* Define to the type of an unsigned integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef uint32_t /* Define to the type of an unsigned integer type of width exactly 8 bits if such a type exists and the standard includes do not define it. */ #undef uint8_t selint-1.2.1/tests/0000755000175100001710000000000014167117420011154 500000000000000selint-1.2.1/tests/sample_configs/0000755000175100001710000000000014167117420014145 500000000000000selint-1.2.1/tests/sample_configs/severity_convention.conf0000644000175100001710000000003014167117255021047 00000000000000severity = "convention" selint-1.2.1/tests/sample_configs/check_config.conf0000644000175100001710000000265414167117255017353 00000000000000# This is the configuration file for SELint. The global configuration file # is the default if no other configuration is provided, but can be overridden # by user specific and project specific confgurations, or a configuration file # can be provided on the command line. # Set the severity level to report. Options are "convention", "style", # "warning", "error" and "fatal". SELint will report all errors at or above # the selected level severity = "convention" # Check enabling works as follows each step may override the one prior: # 1. All checks at or above the set severity level are enabled by default # 2. Checks may be disabled using the "disable" option below # 3. Checks may be enabled in either normal or source modes using the "enable_normal" and "enable_source" options below # 4. Checks may be disabled on the command line using the -d option # 5. Checks may be enabled on the command line using the -e option # Uncomment and modify to disable selected checks. This can be overridden on # the command line disable = { E-003, E-004 } # enable description enable_normal = { } enable_source = { E-003 } # Modules.conf location. If you are running SELint in "source mode", you need # to supply a modules.conf file in order to run all checks. SELint will look # in the default location of policy/modules.conf from the directory where it # is run. To use a different path specify it here. #modules_conf_path = policy/modules.conf selint-1.2.1/tests/sample_configs/severity_warning.conf0000644000175100001710000000002514167117255020336 00000000000000severity = "warning" selint-1.2.1/tests/sample_configs/refpolicy_ordering.conf0000644000175100001710000000003514167117255020625 00000000000000ordering_rules = "refpolicy" selint-1.2.1/tests/sample_configs/order_requires.conf0000644000175100001710000000016114167117255017772 00000000000000ordering_requires = { bool, attribute, attribute_role, type, class, role } ordering_requires_same_flavor = false selint-1.2.1/tests/sample_configs/severity_style.conf0000644000175100001710000000002314167117255020027 00000000000000severity = "style" selint-1.2.1/tests/sample_configs/bad_format_2.conf0000644000175100001710000000266114167117255017266 00000000000000# This is the configuration file for SELint. The global configuration file # is the default if no other configuration is provided, but can be overridden # by user specific and project specific confgurations, or a configuration file # can be provided on the command line. # Set the severity level to report. Options are "convention", "style", # "warning", "error" and "fatal". SELint will report all errors at or above # the selected level severity = "convention" = 43 # Check enabling works as follows each step may override the one prior: # 1. All checks at or above the set severity level are enabled by default # 2. Checks may be disabled using the "disable" option below # 3. Checks may be enabled in either normal or source modes using the "enable_normal" and "enable_source" options below # 4. Checks may be disabled on the command line using the -d option # 5. Checks may be enabled on the command line using the -e option # Uncomment and modify to disable selected checks. This can be overridden on # the command line disable = { E-003, E-004 } # enable description enable_normal = { } enable_source = { E-003 } # Modules.conf location. If you are running SELint in "source mode", you need # to supply a modules.conf file in order to run all checks. SELint will look # in the default location of policy/modules.conf from the directory where it # is run. To use a different path specify it here. #modules_conf_path = policy/modules.conf selint-1.2.1/tests/sample_configs/severity_fatal.conf0000644000175100001710000000002314167117255017756 00000000000000severity = "fatal" selint-1.2.1/tests/sample_configs/bad_order.conf0000644000175100001710000000004214167117255016657 00000000000000ordering_rules = "invalid-option" selint-1.2.1/tests/sample_configs/bad_format.conf0000644000175100001710000000267514167117255017052 00000000000000# This is the configuration file for SELint. The global configuration file # is the default if no other configuration is provided, but can be overridden # by user specific and project specific confgurations, or a configuration file # can be provided on the command line. # Set the severity level to report. Options are "convention", "style", # "warning", "error" and "fatal". SELint will report all errors at or above # the selected level severity = "convention" # Parse error ` # Check enabling works as follows each step may override the one prior: # 1. All checks at or above the set severity level are enabled by default # 2. Checks may be disabled using the "disable" option below # 3. Checks may be enabled in either normal or source modes using the "enable_normal" and "enable_source" options below # 4. Checks may be disabled on the command line using the -d option # 5. Checks may be enabled on the command line using the -e option # Uncomment and modify to disable selected checks. This can be overridden on # the command line disable = { E-003, E-004 } # enable description enable_normal = { } enable_source = { E-003 } # Modules.conf location. If you are running SELint in "source mode", you need # to supply a modules.conf file in order to run all checks. SELint will look # in the default location of policy/modules.conf from the directory where it # is run. To use a different path specify it here. #modules_conf_path = policy/modules.conf selint-1.2.1/tests/sample_configs/invalid_option.conf0000644000175100001710000000271414167117255017764 00000000000000# This is the configuration file for SELint. The global configuration file # is the default if no other configuration is provided, but can be overridden # by user specific and project specific confgurations, or a configuration file # can be provided on the command line. # Set the severity level to report. Options are "convention", "style", # "warning", "error" and "fatal". SELint will report all errors at or above # the selected level severity = "convention" bad_option = "thisshouldbreak" # Check enabling works as follows each step may override the one prior: # 1. All checks at or above the set severity level are enabled by default # 2. Checks may be disabled using the "disable" option below # 3. Checks may be enabled in either normal or source modes using the "enable_normal" and "enable_source" options below # 4. Checks may be disabled on the command line using the -d option # 5. Checks may be enabled on the command line using the -e option # Uncomment and modify to disable selected checks. This can be overridden on # the command line disable = { E-003, E-004 } # enable description enable_normal = { } enable_source = { E-003 } # Modules.conf location. If you are running SELint in "source mode", you need # to supply a modules.conf file in order to run all checks. SELint will look # in the default location of policy/modules.conf from the directory where it # is run. To use a different path specify it here. #modules_conf_path = policy/modules.conf selint-1.2.1/tests/sample_configs/severity_error.conf0000644000175100001710000000002314167117255020020 00000000000000severity = "error" selint-1.2.1/tests/sample_configs/severity_invalid.conf0000644000175100001710000000005014167117255020315 00000000000000severity = "this_is_not_a_valid_string" selint-1.2.1/tests/check_ordering.c0000644000175100001710000004202014167117255014212 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "../src/runner.h" #include "../src/ordering.h" #include "../src/maps.h" static enum order_difference_reason always_greater(__attribute__((unused)) const struct ordering_metadata *order_data, __attribute__((unused)) const struct policy_node *first, __attribute__((unused)) const struct policy_node *second) { return 1; } static enum order_difference_reason always_less(__attribute__((unused)) const struct ordering_metadata *order_data, __attribute__((unused)) const struct policy_node *first, __attribute__((unused)) const struct policy_node *second) { return -1; } START_TEST (test_prepare_ordering_metadata) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); head->next = calloc(1, sizeof(struct policy_node)); head->flavor = NODE_TE_FILE; struct policy_node *cur = head->next; cur->flavor = NODE_DECL; cur->next = calloc(1, sizeof(struct policy_node)); cur = cur->next; cur->flavor = NODE_DECL; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->flavor = NODE_DECL; struct check_data data; data.mod_name = strdup("foo"); struct ordering_metadata *o = prepare_ordering_metadata(&data, head); ck_assert_ptr_nonnull(o); ck_assert_ptr_nonnull(o->sections); ck_assert_ptr_nonnull(o->sections->section_name); ck_assert_uint_eq(o->order_node_len, 3); ck_assert_ptr_null(o->nodes[0].node); ck_assert_ptr_null(o->nodes[1].node); ck_assert_ptr_null(o->nodes[2].node); free(data.mod_name); free_ordering_metadata(o); free_policy_node(head); } END_TEST #define POLICIES_DIR SAMPLE_POL_DIR #define UNCOMMON_TE_FILENAME POLICIES_DIR "uncommon.te" START_TEST (test_ordering_uncommon_policy) { struct policy_node *head = parse_one_file(UNCOMMON_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(head); struct check_data data; data.mod_name = strdup("foo"); struct ordering_metadata *o = prepare_ordering_metadata(&data, head); ck_assert_ptr_nonnull(o); calculate_longest_increasing_subsequence(head, o, always_greater); ck_assert_ptr_eq(o->nodes[0].node, head->next); ck_assert_int_eq(o->nodes[0].in_order, 1); free(data.mod_name); free_ordering_metadata(o); free_policy_node(head); cleanup_parsing(); } END_TEST START_TEST (test_calculate_longest_increasing_subsequence) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); head->flavor = NODE_TE_FILE; head->next = calloc(1, sizeof(struct policy_node)); struct policy_node *cur = head->next; cur->flavor = NODE_DECL; cur->next = calloc(1, sizeof(struct policy_node)); cur = cur->next; cur->flavor = NODE_DECL; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->flavor = NODE_DECL; struct check_data data; data.mod_name = strdup("foo"); struct ordering_metadata *o = prepare_ordering_metadata(&data, head); ck_assert_ptr_nonnull(o); calculate_longest_increasing_subsequence(head, o, always_greater); ck_assert_ptr_eq(o->nodes[0].node, head->next); ck_assert_int_eq(o->nodes[0].in_order, 1); free_ordering_metadata(o); o = prepare_ordering_metadata(&data, head); calculate_longest_increasing_subsequence(head, o, always_less); ck_assert_ptr_eq(o->nodes[0].node, head->next); ck_assert_int_eq(o->nodes[0].in_order, 0); free(data.mod_name); free_ordering_metadata(o); free_policy_node(head); } END_TEST START_TEST (test_add_section_info) { struct section_data *sections = calloc(1, sizeof(struct section_data)); add_section_info(sections, "foo", 2); ck_assert_str_eq(sections->section_name, "foo"); ck_assert_int_eq(sections->lines_sum, 2); ck_assert_int_eq(sections->lineno_count, 1); ck_assert_ptr_null(sections->next); add_section_info(sections, "foo", 4); ck_assert_str_eq(sections->section_name, "foo"); ck_assert_int_eq(sections->lines_sum, 6); ck_assert_int_eq(sections->lineno_count, 2); ck_assert_ptr_null(sections->next); add_section_info(sections, "bar", 5); ck_assert_str_eq(sections->section_name, "foo"); ck_assert_int_eq(sections->lines_sum, 6); ck_assert_int_eq(sections->lineno_count, 2); ck_assert_ptr_nonnull(sections->next); ck_assert_str_eq(sections->next->section_name, "bar"); ck_assert_int_eq(sections->next->lines_sum, 5); ck_assert_int_eq(sections->next->lineno_count, 1); ck_assert_ptr_null(sections->next->next); free_section_data(sections); } END_TEST START_TEST (test_get_section) { ck_assert_ptr_null(get_section(NULL)); struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_TE_FILE; ck_assert_ptr_null(get_section(node)); node->flavor = NODE_IF_FILE; ck_assert_ptr_null(get_section(node)); node->flavor = NODE_FC_FILE; ck_assert_ptr_null(get_section(node)); node->flavor = NODE_AV_RULE; node->data.av_data = calloc(1, sizeof(struct av_rule_data)); node->data.av_data->sources = calloc(1, sizeof(struct string_list)); node->data.av_data->sources->string = strdup("foo_t"); ck_assert_str_eq("foo_t", get_section(node)); free_av_rule_data(node->data.av_data); node->data.av_data = NULL; node->flavor = NODE_ROLE_ALLOW; ck_assert_str_eq("_non_ordered", get_section(node)); node->flavor = NODE_DECL; ck_assert_str_eq("_declaration", get_section(node)); node->flavor = NODE_ALIAS; ck_assert_str_eq("_declaration", get_section(node)); node->flavor = NODE_TYPE_ALIAS; ck_assert_str_eq("_declaration", get_section(node)); node->flavor = NODE_TYPE_ATTRIBUTE; ck_assert_str_eq("_declaration", get_section(node)); node->flavor = NODE_OPTIONAL_POLICY; node->first_child = calloc(1, sizeof(struct policy_node)); node->first_child->flavor = NODE_START_BLOCK; node->first_child->next = calloc(1, sizeof(struct policy_node)); node->first_child->next->flavor = NODE_IF_CALL; node->first_child->next->data.ic_data = calloc(1, sizeof(struct if_call_data)); node->first_child->next->data.ic_data->name = strdup("foo_read"); node->first_child->next->data.ic_data->args = calloc(1, sizeof(struct string_list)); node->first_child->next->data.ic_data->args->string = strdup("bar_t"); ck_assert_str_eq("bar_t", get_section(node)); node->flavor = NODE_REQUIRE; ck_assert_str_eq("_non_ordered", get_section(node)); free_policy_node(node); } END_TEST START_TEST (test_calculate_average_lines) { // Make sure no segfault on NULL. No return to check. calculate_average_lines(NULL); struct section_data *sections = calloc(1, sizeof(struct section_data)); sections->section_name = strdup("foo"); sections->lineno_count = 4; sections->lines_sum = 21; sections->next = calloc(1, sizeof(struct section_data)); sections->next->lineno_count = 10; sections->next->lines_sum = 40; calculate_average_lines(sections); ck_assert_float_eq_tol((float) 5.25, sections->avg_line, (float) 0.001); ck_assert_float_eq_tol((float) 4, sections->next->avg_line, (float) 0.001); free_section_data(sections); } END_TEST START_TEST (test_get_local_subsection) { ck_assert_int_eq(LSS_UNKNOWN, get_local_subsection("foo", NULL, ORDER_REF)); struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_AV_RULE; node->data.av_data = calloc(1, sizeof(struct av_rule_data)); node->data.av_data->targets = calloc(1, sizeof(struct string_list)); node->data.av_data->targets->string = strdup("self"); ck_assert_int_eq(LSS_SELF, get_local_subsection("foo", node, ORDER_REF)); free(node->data.av_data->targets->string); node->data.av_data->sources = calloc(1, sizeof(struct string_list)); node->data.av_data->sources->string = strdup("foo_t"); node->data.av_data->targets->string = strdup("foo_log_t"); insert_into_decl_map("foo_t", "foo", DECL_TYPE); insert_into_decl_map("foo_log_t", "foo", DECL_TYPE); insert_into_decl_map("foo_config", "foo", DECL_ATTRIBUTE); ck_assert_int_eq(LSS_OWN, get_local_subsection("foo", node, ORDER_REF)); free(node->data.av_data->targets->string); node->data.av_data->targets->string = strdup("foo_config"); ck_assert_int_eq(LSS_OWN, get_local_subsection("foo", node, ORDER_REF)); free(node->data.av_data->targets->string); node->data.av_data->targets->string = strdup("bar_data_t"); insert_into_decl_map("bar_data_t", "bar", DECL_TYPE); // raw allow to other module. Not mentioned in style guide ck_assert_int_eq(LSS_UNKNOWN, get_local_subsection("foo", node, ORDER_REF)); free_all_maps(); free_policy_node(node); } END_TEST START_TEST (test_get_local_subsection_related_if) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_IF_CALL; node->data.ic_data = malloc(sizeof(struct if_call_data)); node->data.ic_data->name = strdup("foo_if"); node->data.ic_data->args = sl_from_str("foo_t"); insert_into_ifs_map("foo_if", "foo"); insert_into_ifs_map("foo_sub_if", "foo_sub"); ck_assert_int_eq(LSS_OWN, get_local_subsection("foo", node, ORDER_LIGHT)); ck_assert_int_eq(LSS_RELATED, get_local_subsection("foo_sub", node, ORDER_LIGHT)); ck_assert_int_eq(LSS_OTHER, get_local_subsection("foo_sub", node, ORDER_REF)); free(node->data.ic_data->name); node->data.ic_data->name = strdup("foo_sub_if"); ck_assert_int_eq(LSS_OWN, get_local_subsection("foo_sub", node, ORDER_LIGHT)); ck_assert_int_eq(LSS_RELATED, get_local_subsection("foo", node, ORDER_LIGHT)); ck_assert_int_eq(LSS_OTHER, get_local_subsection("foo", node, ORDER_REF)); free_policy_node(node); free_all_maps(); } END_TEST START_TEST (test_compare_nodes_refpolicy) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); struct policy_node *first = calloc(1, sizeof(struct policy_node)); struct policy_node *second = calloc(1, sizeof(struct policy_node)); head->next = first; first->next = second; first->flavor = NODE_DECL; second->flavor = NODE_AV_RULE; second->data.av_data = calloc(1, sizeof(struct av_rule_data)); second->data.av_data->sources = calloc(1, sizeof(struct string_list)); second->data.av_data->sources->string = strdup("foo_t"); struct check_data data; data.mod_name = strdup("foo"); struct ordering_metadata *o = prepare_ordering_metadata(&data, head); ck_assert_int_eq(ORDER_SECTION, compare_nodes_refpolicy(o, first, second)); ck_assert_int_eq(-ORDER_SECTION, compare_nodes_refpolicy(o, second, first)); free_av_rule_data(second->data.av_data); second->data.av_data = NULL; second->flavor = NODE_DECL; first->data.d_data = calloc(1, sizeof(struct declaration_data)); second->data.d_data = calloc(1, sizeof(struct declaration_data)); first->data.d_data->flavor = DECL_BOOL; second->data.d_data->flavor = DECL_ATTRIBUTE; ck_assert_int_eq(ORDER_DECLARATION_SUBSECTION, compare_nodes_refpolicy(o, first, second)); first->data.d_data->flavor = DECL_TYPE; ck_assert_int_eq(-ORDER_DECLARATION_SUBSECTION, compare_nodes_refpolicy(o, first, second)); free(data.mod_name); free_ordering_metadata(o); free_policy_node(head); } END_TEST START_TEST (test_alphabetical_if_calls) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); struct policy_node *first = calloc(1, sizeof(struct policy_node)); struct policy_node *second = calloc(1, sizeof(struct policy_node)); struct policy_node *third = calloc(1, sizeof(struct policy_node)); head->next = first; first->next = second; second->next = third; first->flavor = NODE_IF_CALL; second->flavor = NODE_IF_CALL; third->flavor = NODE_IF_CALL; first->data.ic_data = malloc(sizeof(struct if_call_data)); first->data.ic_data->name = strdup("moduleA_if1"); first->data.ic_data->args = sl_from_str("foo_t"); second->data.ic_data = malloc(sizeof(struct if_call_data)); second->data.ic_data->name = strdup("moduleA_if2"); second->data.ic_data->args = sl_from_str("foo_t"); third->data.ic_data = malloc(sizeof(struct if_call_data)); third->data.ic_data->name = strdup("moduleB_if"); third->data.ic_data->args = sl_from_str("foo_t"); struct check_data data; data.mod_name = strdup("foo"); insert_into_ifs_map("moduleA_if1", "moduleA"); insert_into_ifs_map("moduleA_if2", "moduleA"); insert_into_ifs_map("moduleB_if", "moduleB"); struct ordering_metadata *o = prepare_ordering_metadata(&data, head); ck_assert_int_eq(ORDER_EQUAL, compare_nodes_refpolicy(o, first, second)); ck_assert_int_eq(ORDER_EQUAL, compare_nodes_refpolicy(o, second, first)); ck_assert_int_eq(ORDER_ALPHABETICAL, compare_nodes_refpolicy(o, second, third)); ck_assert_int_eq(-ORDER_ALPHABETICAL, compare_nodes_refpolicy(o, third, second)); free(data.mod_name); free_ordering_metadata(o); free_policy_node(head); } END_TEST START_TEST (test_alphabetical_optionals) { // Setup struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); cur->flavor = NODE_TE_FILE; struct policy_node *head = cur; ck_assert_int_eq(SELINT_SUCCESS, begin_optional_policy(&cur, 1)); ck_assert_int_eq(SELINT_SUCCESS, insert_interface_call(&cur, "moduleA_if", sl_from_str("foo_t"), 2)); ck_assert_int_eq(SELINT_SUCCESS, insert_interface_call(&cur, "moduleD_if", sl_from_str("foo_t"), 2)); ck_assert_int_eq(SELINT_SUCCESS, end_optional_policy(&cur)); ck_assert_int_eq(SELINT_SUCCESS, begin_optional_policy(&cur, 4)); ck_assert_int_eq(SELINT_SUCCESS, insert_interface_call(&cur, "moduleC_if", sl_from_str("foo_t"), 5)); ck_assert_int_eq(SELINT_SUCCESS, insert_interface_call(&cur, "moduleB_if", sl_from_str("foo_t"), 5)); ck_assert_int_eq(SELINT_SUCCESS, end_optional_policy(&cur)); insert_into_ifs_map("moduleA_if", "moduleA"); insert_into_ifs_map("moduleB_if", "moduleB"); insert_into_ifs_map("moduleC_if", "moduleC"); insert_into_ifs_map("moduleD_if", "moduleD"); const struct policy_node *A_call = head->next->first_child->next; const struct policy_node *B_call = head->next->next->first_child->next->next; const struct policy_node *C_call = head->next->next->first_child->next; const struct policy_node *D_call = head->next->first_child->next->next; ck_assert_int_eq(NODE_OPTIONAL_POLICY, head->next->flavor); ck_assert_int_eq(NODE_START_BLOCK, head->next->first_child->flavor); ck_assert_int_eq(NODE_OPTIONAL_POLICY, head->next->next->flavor); ck_assert_int_eq(NODE_START_BLOCK, head->next->next->first_child->flavor); ck_assert_int_eq(NODE_IF_CALL, A_call->flavor); ck_assert_str_eq("moduleA_if", A_call->data.ic_data->name); ck_assert_int_eq(NODE_IF_CALL, B_call->flavor); ck_assert_str_eq("moduleB_if", B_call->data.ic_data->name); ck_assert_int_eq(NODE_IF_CALL, C_call->flavor); ck_assert_str_eq("moduleC_if", C_call->data.ic_data->name); ck_assert_int_eq(NODE_IF_CALL, D_call->flavor); ck_assert_str_eq("moduleD_if", D_call->data.ic_data->name); struct check_data data; data.mod_name = strdup("foo"); struct ordering_metadata *o = prepare_ordering_metadata(&data, head); // Actual tests // sort distinct optiona blocks ck_assert_int_eq(ORDER_ALPHABETICAL, compare_nodes_refpolicy(o, head->next, head->next->next)); ck_assert_int_eq(-ORDER_ALPHABETICAL, compare_nodes_refpolicy(o, head->next->next, head->next)); // do not sort inside optional block ck_assert_int_eq(ORDER_EQUAL, compare_nodes_refpolicy(o, C_call, B_call)); ck_assert_int_eq(ORDER_EQUAL, compare_nodes_refpolicy(o, B_call, C_call)); ck_assert_int_eq(ORDER_ALPHABETICAL, compare_nodes_refpolicy(o, A_call, C_call)); ck_assert_int_eq(-ORDER_ALPHABETICAL, compare_nodes_refpolicy(o, C_call, A_call)); // do not sort on non-first ndoes ck_assert_int_eq(ORDER_EQUAL, compare_nodes_refpolicy(o, D_call, C_call)); ck_assert_int_eq(ORDER_EQUAL, compare_nodes_refpolicy(o, C_call, D_call)); // Cleanup free(data.mod_name); free_ordering_metadata(o); free_policy_node(head); cleanup_parsing(); } END_TEST static Suite *ordering_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Ordering"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_prepare_ordering_metadata); tcase_add_test(tc_core, test_ordering_uncommon_policy); tcase_add_test(tc_core, test_calculate_longest_increasing_subsequence); tcase_add_test(tc_core, test_add_section_info); tcase_add_test(tc_core, test_get_section); tcase_add_test(tc_core, test_calculate_average_lines); tcase_add_test(tc_core, test_get_local_subsection); tcase_add_test(tc_core, test_get_local_subsection_related_if); tcase_add_test(tc_core, test_compare_nodes_refpolicy); tcase_add_test(tc_core, test_alphabetical_if_calls); tcase_add_test(tc_core, test_alphabetical_optionals); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = ordering_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_runner.c0000644000175100001710000000476714167117255013732 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "../src/string_list.h" #include "../src/runner.h" START_TEST (test_is_check_enabled) { struct string_list *con_e = calloc(1, sizeof(struct string_list)); con_e->string = strdup("S-001"); struct string_list *con_d = calloc(1, sizeof(struct string_list)); con_d->string = strdup("S-001"); con_d->next = calloc(1, sizeof(struct string_list)); con_d->next->string = strdup("S-002"); con_d->next->next = calloc(1, sizeof(struct string_list)); con_d->next->next->string = strdup("S-003"); struct string_list *cl_e = calloc(1, sizeof(struct string_list)); cl_e->string = strdup("S-002"); struct string_list *cl_d = calloc(1, sizeof(struct string_list)); cl_d->string = strdup("S-004"); ck_assert_int_eq(is_check_enabled("S-001", con_e, con_d, cl_e, cl_d, 0), 1); ck_assert_int_eq(is_check_enabled("S-002", con_e, con_d, cl_e, cl_d, 0), 1); ck_assert_int_eq(is_check_enabled("S-003", con_e, con_d, cl_e, cl_d, 0), 0); ck_assert_int_eq(is_check_enabled("S-004", con_e, con_d, cl_e, cl_d, 0), 0); ck_assert_int_eq(is_check_enabled("S-001", con_e, con_d, cl_e, cl_d, 1), 0); ck_assert_int_eq(is_check_enabled("S-002", con_e, con_d, cl_e, cl_d, 1), 1); ck_assert_int_eq(is_check_enabled("S-003", con_e, con_d, cl_e, cl_d, 1), 0); ck_assert_int_eq(is_check_enabled("S-004", con_e, con_d, cl_e, cl_d, 1), 0); free_string_list(con_e); free_string_list(con_d); free_string_list(cl_e); free_string_list(cl_d); } END_TEST static Suite *runner_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Runner"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_is_check_enabled); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = runner_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/sample_policy_files/0000755000175100001710000000000014167117420015176 500000000000000selint-1.2.1/tests/sample_policy_files/basic.fc0000644000175100001710000000053514167117255016522 00000000000000/usr/bin/basic -- gen_context(system_u:object_r:basic_t, s0) /etc/basic(/.*)? gen_context(system_u:object_r:basic_conf_t, s0) /var/www/basic gen_this_is_an_error(system_u:obect_r:basic_conf_t, s0) /var/log/basic.log -- system_u:object_r:basic_log_t:s0 /var/www/basic/basic.conf -- gen_context(system_u:object_r:basic_conf_t, s0, c1) selint-1.2.1/tests/sample_policy_files/bad_modules.conf0000644000175100001710000000023414167117255020250 00000000000000# This is an example modules.conf # It has comments that can include = characters # And blank lines sysadm = base = error # sudo = module games = off selint-1.2.1/tests/sample_policy_files/declaring_template.te0000644000175100001710000000032214167117255021276 00000000000000policy_module(delcaring_template, 1.0.0) declaring_template(foo, bar) # this will not declare the types in the current module # but there will be a S-004 issued declaring_helper_if() declaring_helper_temp() selint-1.2.1/tests/sample_policy_files/disable_comment.if0000644000175100001710000000006514167117255020572 00000000000000interface(`foo', ` #selint-disable:S-012 # empty ') selint-1.2.1/tests/sample_policy_files/disable_comment.te0000644000175100001710000000013614167117255020603 00000000000000policy_module(comment, 1.0) type foo_t; allow foo_t bar_t:file write; #selint-disable:W-001 selint-1.2.1/tests/sample_policy_files/syntax_error.te0000644000175100001710000000015614167117255020217 00000000000000policy_module(syntax_error, 1.0 type no_semicolon_t allow no_semicolon_t other_thing_t:file { read write }; selint-1.2.1/tests/sample_policy_files/basic.if0000644000175100001710000000051114167117255016522 00000000000000## Some interfaces for test # Comments get ignored interface(`basic_domtrans',` gen_require(` type basic_t, basic_exec_t; ') domtrans_pattern($1, basic_exec_t, basic_t) ') template(`basic_template',` gen_require(` type basic_t; ') type $1_basic_t; allow $1_basic_t basic_t:process signal; ') selint-1.2.1/tests/sample_policy_files/ifdef_block.te0000644000175100001710000000061614167117255017710 00000000000000policy_module(ifdef_block, 1.0) ifelse(`bool1', `true', ` # comment allow source1 target1:cls perm1; # comment allow source1 target1:cls perm2; ', `bool2', `true', ` # comment allow source2 target2:cls perm1; # comment allow source2 target2:cls perm2; ', ` # comment allow source3 target3:cls perm1; # comment allow source3 target3:cls perm2; ') selint-1.2.1/tests/sample_policy_files/perms.spt0000644000175100001710000000241314167117255017002 00000000000000define(`getattr_dir_perms', `{ getattr }') define(`search_dir_perms', `{ open search getattr_dir_perms }') define(`read_dir_perms', `{ ioctl lock read search_dir_perms }') define(`add_name_dir_perms', `{ add_name ioctl lock write search_dir_perms }') define(`remove_name_dir_perms', `{ ioctl lock remove_name write search_dir_perms }') define(`rw_dir_perms', `{ add_name_dir_perms remove_name_dir_perms read_dir_perms }') define(`control_dir_perms', `{ create setattr link unlink rename reparent rmdir rw_dir_perms }') define(`relabel_dir_perms', `{ relabelfrom relabelto getattr_dir_perms }') define(`uncovered_dir_perms', `{ search open audit_access }') define(`getattr_file_perms', `{ getattr }') define(`read_no_lock_file_perms', `{ ioctl open read getattr_file_perms }') define(`read_file_perms', `{ lock read_no_lock_file_perms }') define(`write_file_perms', `{ ioctl lock open write getattr_file_perms }') define(`rw_no_open_file_perms', `{ ioctl lock read write getattr_file_perms }') define(`rw_file_perms', `{ open rw_no_open_file_perms }') define(`rename_file_perms', `{ rename getattr_file_perms }') define(`control_file_perms', `{ append create link rename setattr unlink rw_file_perms }') define(`relabel_file_perms', `{ relabelfrom relabelto getattr_file_perms }') selint-1.2.1/tests/sample_policy_files/blocks.te0000644000175100001710000000011714167117255016732 00000000000000policy_module(blocks, 1.0) # Empty optional_policy block optional_policy(` ') selint-1.2.1/tests/sample_policy_files/bad_obj_perm_sets.spt0000644000175100001710000000014714167117255021317 00000000000000######################################## # # Custom define # define(`ifndef',`ifdef(`$1',`$3',`$2')') selint-1.2.1/tests/sample_policy_files/empty.te0000644000175100001710000000000014167117255016602 00000000000000selint-1.2.1/tests/sample_policy_files/modules.conf0000644000175100001710000000022514167117255017442 00000000000000# This is an example modules.conf # It has comments that can include = characters # And blank lines sysadm = base # sudo = module games = off selint-1.2.1/tests/sample_policy_files/none_context.fc0000644000175100001710000000002614167117255020137 00000000000000/path/path <> selint-1.2.1/tests/sample_policy_files/extended_perms.te0000644000175100001710000000126214167117255020465 00000000000000policy_module(extended_perms, 1.0) type basic_t; type basic_dev_t; allow basic_t basic_dev_t:chr_file ioctl; allowxperm basic_t basic_dev_t:chr_file ioctl ~0x8927; allowxperm basic_t basic_dev_t:chr_file ioctl 35072; allowxperm basic_t basic_dev_t:chr_file ioctl { 0027 0028 }; allowxperm basic_t basic_dev_t:chr_file ioctl { 0 0x00 }; allowxperm basic_t basic_dev_t:chr_file ioctl { 0x0000 - 0x00ff }; allowxperm basic_t basic_dev_t:chr_file ioctl { 1024 - 2048 }; dontauditxperm basic_t basic_dev_t:chr_file ioctl { 1024-2048 35072 }; auditallowxperm basic_t basic_dev_t:chr_file ioctl ioctl_macro; neverallowxperm basic_t basic_dev_t:chr_file ioctl { ioctl_macro 0x40ff-0x41ff }; selint-1.2.1/tests/sample_policy_files/uncommon.te0000644000175100001710000000642014167117255017313 00000000000000module uncommon 1; # Use uncommon policy constructs to ensure the parser can handle them without breaking require { type bar_t; role system_r, user_r; } type baz_t alias { old_baz_t older_baz_t }; type this_shouldnt_be_allowed_t alias other_name_t, attr_name; permissive foo_t; sid netmsg gen_context(system_u:object_r:netlabel_peer_t,mls_systemhigh) portcon udp 7007 gen_context(system_u:object_r:afs_bos_port_t,s0) portcon udp 7007 gen_context(system_u:object_r:afs_bos_port_t,s0:c2) portcon udp 7007 gen_context(system_u:object_r:afs_bos_port_t,s0,s1:c0.c225) portcon udp 7007-7008 gen_context(system_u:object_r:afs_bos_port_t,s0) fs_use_trans devtmpfs gen_context(system_u:object_r:device_t,s0); genfscon sysfs /devices/system/cpu/online gen_context(system_u:object_r:cpu_online_t,s0) fs_use_xattr btrfs gen_context(system_u:object_r:fs_t,s0); fs_use_task eventpollfs gen_context(system_u:object_r:fs_t,s0); bool bool_one; attribute_role rattr; class file { read write open }; roleattribute system_r mount_roles; optional_policy(` ; ') optional_policy(` foo_read(bar_t) ',` # else foo_write(bar_t) ') netifcon lo gen_context(system_u:object_r:lo_netif_t,s0 - mls_systemhigh) gen_context(system_u:object_r:unlabeled_t,s0 - mls_systemhigh) nodecon 127.0.0.1 255.255.255.255 gen_context(system_u:object_r:system_t:s0) nodecon ::5 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff gen_context(system_u:object_r:system_t:s0) nodecon ::ffff:127.0.0.1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff gen_context(system_u:object_r:lo_node_t,s0) if (!bool_one) { allow foo_t bar_t:file open; } if (bool_one && ( bool_three || ( bool_four != bool_five))) { allow foo_t baz_t:file write; } if (bool_one == bool_two) { allow foo_t baz_t:file relabelto; } # Interface with a missing comma foo_if(foo_t, bar_t baz_t) allow system_r user_r; empty_interfaces_are_legal() gen_require( type no_backticks_t; role no_backticks_r; ) gen_tunable(`hello',world) gen_tunable(hello,world) define(yes, no) define(`list_of_things', `{ thing1 thing2 }') typebounds foo_t bar_t; call_with_backtick_args(foo_t,bar_t,`in') dollar_sign_in_string("foo1-$3_$2") ifdef(`test',` gen_require(` type nesting_t; ') ') foo_filter_template(synchronizer,synchronizer,`') role_transition foo_r bar_exec_t bar_r; role_transition foo_r baz_exec_t:{file lnk_file sock_file} baz_r; genfscon rootfs / -- gen_context(system_u:object_r:rootfs_t, s0) genfscon rootfs / -l gen_context(system_u:object_r:rootfs_t, s0) #exceptions neverallow { domain -foo_t } secret_stuff_t:file read; empty_string_first(`', foo_t) type type_t alias { alias1 alias2 alias3 }, attribute1; type type_t alias { alias1 alias2 alias3 }, attribute1, attribute2, attribute3; refpolicywarn(`$0($*) has been deprecated, please use foo(); instead.') xperm_macro(foo_t, bar_t, 0x1234) xperm_macro(foo_t, bar_t, { 0x5000 - 0x50ff 1234 }) gen_user(my_user_u,, some_role_r, s0, s0 - mls_systemhigh, mcs_allcats) bare_word bare_word; ifdef(`foo',` bare_word ') ifdef(`foo',` # comment bare_word ') define(`not_foo',`-foo_t') define(`foobar') ifelse(`$1',,, ` refpolicywarn(`dollar one defined') ') example_interface(foo_t, `s0:c0') example_interface(foo_t, `s15:c100.c102') range_transition foo_t foo_t:file s0:c0 - s15:c100.c102; example_interface(foo_t, `s0:c0 - s15:c100.c102') selint-1.2.1/tests/sample_policy_files/declaring_template.if0000644000175100001710000000050214167117255021264 00000000000000template(`declaring_template',` type prefix_$1_suffix; type $2_t; role $2_r; ') interface(`declaring_helper_if',` # this will not declare the types in the current module # but there will be a S-004 issued declaring_template(hello, world) ') template(`declaring_helper_temp',` declaring_template(good, morning) ') selint-1.2.1/tests/sample_policy_files/obj_perm_sets.spt0000644000175100001710000000117714167117255020515 00000000000000######################################## # # Macros for sets of classes # # # All directory and file classes # define(`dir_file_class_set', `{ dir file_class_set }') ######################################## # # Macros for sets of permissions # # # Permissions to mount and unmount file systems. # define(`mount_fs_perms', `{ mount remount unmount getattr }') # deprecated define(`remount_fs_perms',` { remount getattr } refpolicywarn(`remount_fs_perms is deprecated') ') # # Permissions for using sockets. # define(`rw_socket_perms', `{ ioctl read getattr write setattr append bind connect getopt setopt shutdown }') selint-1.2.1/tests/sample_policy_files/basic.te0000644000175100001710000000045714167117255016545 00000000000000policy_module(basic) type basic_t; type basic_exec_t; allow basic_t basic_exec_t:file { read execute entrypoint }; optional_policy(` allow basic_t foo_t:file *; allow basic_t foo_t:dir read; ') optional_policy(` allow basic_t bar_t:file ~{ read write }; ') allow basic_t self:capability chown; selint-1.2.1/tests/sample_policy_files/bad_role_allow.te0000644000175100001710000000011414167117255020417 00000000000000policy_module(bad_role_allow, 1.0) # Not legal dontaudit staff_r sysadm_r; selint-1.2.1/tests/sample_policy_files/nested_templates.if0000644000175100001710000000031114167117255020777 00000000000000## Nesting of template calls template(`outer',` middle($1,$3,$2) ') template(`middle',` inner($1, $2, $3) ') template(`inner',` type $1_t; type $2_foo_t; type $3_bar_t; ') selint-1.2.1/tests/sample_policy_files/bool_declarations.te0000644000175100001710000000025714167117255021145 00000000000000policy_module(bool_declarations, 1.0.0) bool bool_one; gen_bool(bool_two, false) gen_bool(bool_three,true) gen_tunable(`tunable_one', true) gen_tunable(tunable_two,false) selint-1.2.1/tests/sample_policy_files/access_vectors0000644000175100001710000000104714167117255020057 00000000000000common file { ioctl read write create getattr setattr lock relabelfrom relabelto append map unlink link rename execute quotaon mounton audit_access open execmod watch watch_mount watch_sb watch_with_perm watch_reads } class dir inherits file { add_name remove_name reparent search rmdir } class file inherits file { execute_no_trans entrypoint } class lnk_file inherits file class chr_file inherits file class blk_file inherits file class sock_file inherits file class fifo_file inherits file class fd { use } selint-1.2.1/tests/sample_policy_files/with_m4.fc0000644000175100001710000000024514167117255017012 00000000000000/this/is/a/path -l gen_context(system_u:object_r:abcdefg_t, s0) ifdef(`distro_windows',` /this/is/also/a/path gen_context(system_u:object_r:hijklmn_t, s0) ') selint-1.2.1/tests/sample_av/0000755000175100001710000000000014167117420013123 500000000000000selint-1.2.1/tests/sample_av/file/0000755000175100001710000000000014167117420014042 500000000000000selint-1.2.1/tests/sample_av/file/index0000644000175100001710000000000114167117255015011 000000000000006selint-1.2.1/tests/sample_av/file/perms/0000755000175100001710000000000014167117420015170 500000000000000selint-1.2.1/tests/sample_av/file/perms/lock0000644000175100001710000000000114167117255015760 000000000000007selint-1.2.1/tests/sample_av/file/perms/relabelto0000644000175100001710000000000114167117255017001 000000000000009selint-1.2.1/tests/sample_av/file/perms/link0000644000175100001710000000000214167117255015766 0000000000000013selint-1.2.1/tests/sample_av/file/perms/swapon0000644000175100001710000000000214167117255016340 0000000000000016selint-1.2.1/tests/sample_av/file/perms/mounton0000644000175100001710000000000214167117255016530 0000000000000018selint-1.2.1/tests/sample_av/file/perms/open0000644000175100001710000000000214167117255015772 0000000000000022selint-1.2.1/tests/sample_av/file/perms/quotaon0000644000175100001710000000000214167117255016517 0000000000000017selint-1.2.1/tests/sample_av/file/perms/append0000644000175100001710000000000214167117255016300 0000000000000010selint-1.2.1/tests/sample_av/file/perms/write0000644000175100001710000000000114167117255016162 000000000000003selint-1.2.1/tests/sample_av/file/perms/entrypoint0000644000175100001710000000000214167117255017244 0000000000000020selint-1.2.1/tests/sample_av/file/perms/ioctl0000644000175100001710000000000114167117255016142 000000000000001selint-1.2.1/tests/sample_av/file/perms/getattr0000644000175100001710000000000114167117255016502 000000000000005selint-1.2.1/tests/sample_av/file/perms/execute_no_trans0000644000175100001710000000000214167117255020376 0000000000000019selint-1.2.1/tests/sample_av/file/perms/relabelfrom0000644000175100001710000000000114167117255017322 000000000000008selint-1.2.1/tests/sample_av/file/perms/unlink0000644000175100001710000000000214167117255016331 0000000000000012selint-1.2.1/tests/sample_av/file/perms/execmod0000644000175100001710000000000214167117255016455 0000000000000021selint-1.2.1/tests/sample_av/file/perms/map0000644000175100001710000000000214167117255015606 0000000000000011selint-1.2.1/tests/sample_av/file/perms/read0000644000175100001710000000000114167117255015743 000000000000002selint-1.2.1/tests/sample_av/file/perms/execute0000644000175100001710000000000214167117255016473 0000000000000015selint-1.2.1/tests/sample_av/file/perms/audit_access0000644000175100001710000000000214167117255017460 0000000000000023selint-1.2.1/tests/sample_av/file/perms/setattr0000644000175100001710000000000114167117255016516 000000000000006selint-1.2.1/tests/sample_av/file/perms/rename0000644000175100001710000000000214167117255016300 0000000000000014selint-1.2.1/tests/sample_av/file/perms/create0000644000175100001710000000000114167117255016273 000000000000004selint-1.2.1/tests/sample_av/x_cursor/0000755000175100001710000000000014167117420014767 500000000000000selint-1.2.1/tests/sample_av/x_cursor/index0000644000175100001710000000000214167117255015737 0000000000000038selint-1.2.1/tests/sample_av/x_cursor/perms/0000755000175100001710000000000014167117420016115 500000000000000selint-1.2.1/tests/sample_av/x_cursor/perms/use0000644000175100001710000000000114167117255016551 000000000000007selint-1.2.1/tests/sample_av/x_cursor/perms/destroy0000644000175100001710000000000114167117255017446 000000000000002selint-1.2.1/tests/sample_av/x_cursor/perms/write0000644000175100001710000000000114167117255017107 000000000000004selint-1.2.1/tests/sample_av/x_cursor/perms/getattr0000644000175100001710000000000114167117255017427 000000000000005selint-1.2.1/tests/sample_av/x_cursor/perms/read0000644000175100001710000000000114167117255016670 000000000000003selint-1.2.1/tests/sample_av/x_cursor/perms/setattr0000644000175100001710000000000114167117255017443 000000000000006selint-1.2.1/tests/sample_av/x_cursor/perms/create0000644000175100001710000000000114167117255017220 000000000000001selint-1.2.1/tests/sample_av/socket/0000755000175100001710000000000014167117420014413 500000000000000selint-1.2.1/tests/sample_av/socket/index0000644000175100001710000000000214167117255015363 0000000000000014selint-1.2.1/tests/sample_av/socket/perms/0000755000175100001710000000000014167117420015541 500000000000000selint-1.2.1/tests/sample_av/socket/perms/lock0000644000175100001710000000000114167117255016331 000000000000007selint-1.2.1/tests/sample_av/socket/perms/relabelto0000644000175100001710000000000114167117255017352 000000000000009selint-1.2.1/tests/sample_av/socket/perms/setopt0000644000175100001710000000000214167117255016720 0000000000000017selint-1.2.1/tests/sample_av/socket/perms/bind0000644000175100001710000000000214167117255016316 0000000000000012selint-1.2.1/tests/sample_av/socket/perms/accept0000644000175100001710000000000214167117255016641 0000000000000015selint-1.2.1/tests/sample_av/socket/perms/getopt0000644000175100001710000000000214167117255016704 0000000000000016selint-1.2.1/tests/sample_av/socket/perms/listen0000644000175100001710000000000214167117255016700 0000000000000014selint-1.2.1/tests/sample_av/socket/perms/connect0000644000175100001710000000000214167117255017033 0000000000000013selint-1.2.1/tests/sample_av/socket/perms/send_msg0000644000175100001710000000000214167117255017201 0000000000000022selint-1.2.1/tests/sample_av/socket/perms/append0000644000175100001710000000000214167117255016651 0000000000000010selint-1.2.1/tests/sample_av/socket/perms/write0000644000175100001710000000000114167117255016533 000000000000003selint-1.2.1/tests/sample_av/socket/perms/ioctl0000644000175100001710000000000114167117255016513 000000000000001selint-1.2.1/tests/sample_av/socket/perms/getattr0000644000175100001710000000000114167117255017053 000000000000005selint-1.2.1/tests/sample_av/socket/perms/name_bind0000644000175100001710000000000214167117255017316 0000000000000023selint-1.2.1/tests/sample_av/socket/perms/relabelfrom0000644000175100001710000000000114167117255017673 000000000000008selint-1.2.1/tests/sample_av/socket/perms/map0000644000175100001710000000000214167117255016157 0000000000000011selint-1.2.1/tests/sample_av/socket/perms/recvfrom0000644000175100001710000000000214167117255017225 0000000000000019selint-1.2.1/tests/sample_av/socket/perms/read0000644000175100001710000000000114167117255016314 000000000000002selint-1.2.1/tests/sample_av/socket/perms/recv_msg0000644000175100001710000000000214167117255017207 0000000000000021selint-1.2.1/tests/sample_av/socket/perms/shutdown0000644000175100001710000000000214167117255017255 0000000000000018selint-1.2.1/tests/sample_av/socket/perms/setattr0000644000175100001710000000000114167117255017067 000000000000006selint-1.2.1/tests/sample_av/socket/perms/sendto0000644000175100001710000000000214167117255016676 0000000000000020selint-1.2.1/tests/sample_av/socket/perms/create0000644000175100001710000000000114167117255016644 000000000000004selint-1.2.1/tests/test_utils.h0000644000175100001710000000137214167117255013455 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "../src/tree.h" #define EXAMPLE_TYPE_1 "foo_t" #define EXAMPLE_TYPE_2 "bar_t" #define EXAMPLE_TYPE_3 "baz_t" struct av_rule_data * make_example_av_rule(void); selint-1.2.1/tests/check_selint_config.c0000644000175100001710000001476514167117255015243 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "../src/string_list.h" #include "../src/selint_config.h" #include "../src/ordering.h" #define CONFIGS_DIR SAMPLE_CONF_DIR #define SEVERITY_CONVENTION_FILENAME CONFIGS_DIR "severity_convention.conf" #define SEVERITY_STYLE_FILENAME CONFIGS_DIR "severity_style.conf" #define SEVERITY_WARNING_FILENAME CONFIGS_DIR "severity_warning.conf" #define SEVERITY_ERROR_FILENAME CONFIGS_DIR "severity_error.conf" #define SEVERITY_FATAL_FILENAME CONFIGS_DIR "severity_fatal.conf" #define CHECKS_FILENAME CONFIGS_DIR "check_config.conf" #define REFPOL_ORDERING_FILENAME CONFIGS_DIR "refpolicy_ordering.conf" #define ORDER_REQUIRES_FILENAME CONFIGS_DIR "order_requires.conf" #define BAD_FORMAT_1 CONFIGS_DIR "bad_format.conf" #define BAD_FORMAT_2 CONFIGS_DIR "bad_format_2.conf" #define BAD_OPTION CONFIGS_DIR "invalid_option.conf" #define BAD_SEVERITY CONFIGS_DIR "severity_invalid.conf" #define BAD_ORDER CONFIGS_DIR "bad_order.conf" START_TEST (test_parse_config_severity) { char severity = '\0'; struct config_check_data ccd; ck_assert_int_eq(SELINT_SUCCESS, parse_config(SEVERITY_CONVENTION_FILENAME, 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq('C', severity); ck_assert_int_eq(SELINT_SUCCESS, parse_config(SEVERITY_STYLE_FILENAME, 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq('S', severity); ck_assert_int_eq(SELINT_SUCCESS, parse_config(SEVERITY_WARNING_FILENAME, 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq('W', severity); ck_assert_int_eq(SELINT_SUCCESS, parse_config(SEVERITY_ERROR_FILENAME, 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq('E', severity); ck_assert_int_eq(SELINT_SUCCESS, parse_config(SEVERITY_FATAL_FILENAME, 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq('F', severity); } END_TEST START_TEST (test_parse_config_checks) { char severity = '\0'; struct string_list *dis = NULL; struct string_list *en = NULL; struct string_list *cfm = NULL; struct config_check_data ccd; ck_assert_int_eq(SELINT_SUCCESS, parse_config(CHECKS_FILENAME, 0, &severity, &dis, &en, &cfm, &ccd)); ck_assert_ptr_nonnull(dis); ck_assert_str_eq(dis->string, "E-003"); ck_assert_str_eq(dis->next->string, "E-004"); ck_assert_ptr_null(dis->next->next); ck_assert_ptr_null(en); free_string_list(dis); dis = NULL; free_string_list(en); en = NULL; ck_assert_int_eq(SELINT_SUCCESS, parse_config(CHECKS_FILENAME, 1, &severity, &dis, &en, &cfm, &ccd)); ck_assert_ptr_nonnull(dis); ck_assert_str_eq(dis->string, "E-003"); ck_assert_str_eq(dis->next->string, "E-004"); ck_assert_ptr_null(dis->next->next); ck_assert_str_eq(en->string, "E-003"); ck_assert_ptr_null(en->next); free_string_list(dis); free_string_list(en); } END_TEST START_TEST (test_parse_config_ordering_rules) { char severity = '\0'; struct config_check_data ccd; ck_assert_int_eq(SELINT_SUCCESS, parse_config(REFPOL_ORDERING_FILENAME, 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq(ORDER_REF, ccd.order_conf); } END_TEST START_TEST (test_parse_config_ordering_requires) { char severity = '\0'; struct config_check_data ccd; // default ck_assert_int_eq(SELINT_SUCCESS, parse_config("", 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq(DECL_BOOL, ccd.order_requires[0]); ck_assert_int_eq(DECL_CLASS, ccd.order_requires[1]); ck_assert_int_eq(DECL_ROLE, ccd.order_requires[2]); ck_assert_int_eq(DECL_ATTRIBUTE_ROLE, ccd.order_requires[3]); ck_assert_int_eq(DECL_ATTRIBUTE, ccd.order_requires[4]); ck_assert_int_eq(DECL_TYPE, ccd.order_requires[5]); ck_assert_int_eq(true, ccd.ordering_requires_same_flavor); // custom ck_assert_int_eq(SELINT_SUCCESS, parse_config(ORDER_REQUIRES_FILENAME, 0, &severity, NULL, NULL, NULL, &ccd)); ck_assert_int_eq(DECL_BOOL, ccd.order_requires[0]); ck_assert_int_eq(DECL_ATTRIBUTE, ccd.order_requires[1]); ck_assert_int_eq(DECL_ATTRIBUTE_ROLE, ccd.order_requires[2]); ck_assert_int_eq(DECL_TYPE, ccd.order_requires[3]); ck_assert_int_eq(DECL_CLASS, ccd.order_requires[4]); ck_assert_int_eq(DECL_ROLE, ccd.order_requires[5]); ck_assert_int_eq(false, ccd.ordering_requires_same_flavor); } END_TEST START_TEST (test_bad_configs) { char severity = '\0'; struct string_list *dis = NULL; struct string_list *en = NULL; struct string_list *cfm = NULL; struct config_check_data ccd; ck_assert_int_eq(SELINT_CONFIG_PARSE_ERROR, parse_config(BAD_FORMAT_1, 0, &severity, &dis, &en, &cfm, &ccd)); ck_assert_ptr_null(dis); ck_assert_ptr_null(en); ck_assert_int_eq('\0', severity); ck_assert_int_eq(SELINT_CONFIG_PARSE_ERROR, parse_config(BAD_FORMAT_2, 0, &severity, &dis, &en, &cfm, &ccd)); ck_assert_ptr_null(dis); ck_assert_ptr_null(en); ck_assert_int_eq('\0', severity); ck_assert_int_eq(SELINT_CONFIG_PARSE_ERROR, parse_config(BAD_OPTION, 0, &severity, &dis, &en, &cfm, &ccd)); ck_assert_ptr_null(dis); ck_assert_ptr_null(en); ck_assert_int_eq('\0', severity); ck_assert_int_eq(SELINT_CONFIG_PARSE_ERROR, parse_config(BAD_SEVERITY, 0, &severity, &dis, &en, &cfm, &ccd)); ck_assert_ptr_null(dis); ck_assert_ptr_null(en); ck_assert_int_eq('\0', severity); ck_assert_int_eq(SELINT_CONFIG_PARSE_ERROR, parse_config(BAD_ORDER, 0, &severity, &dis, &en, &cfm, &ccd)); ck_assert_ptr_null(dis); ck_assert_ptr_null(en); ck_assert_int_eq('C', severity); } END_TEST static Suite *selint_config_suite(void) { Suite *s; TCase *tc_core; s = suite_create("SELint_config"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_parse_config_severity); tcase_add_test(tc_core, test_parse_config_checks); tcase_add_test(tc_core, test_parse_config_ordering_rules); tcase_add_test(tc_core, test_parse_config_ordering_requires); tcase_add_test(tc_core, test_bad_configs); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = selint_config_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_template.c0000644000175100001710000002032714167117255014222 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "../src/parse_functions.h" #include "../src/template.h" #include "../src/parse.h" #include "../src/maps.h" #define POLICIES_DIR SAMPLE_POL_DIR #define NESTED_IF_FILENAME POLICIES_DIR "nested_templates.if" #define DECLARING_IF_FILENAME POLICIES_DIR "declaring_template.if" #define DECLARING_TE_FILENAME POLICIES_DIR "declaring_template.te" START_TEST (test_replace_m4) { const char *orig1 = "$1_t"; struct string_list *args = calloc(1,sizeof(struct string_list)); args->string = strdup("foo"); args->next = calloc(1,sizeof(struct string_list)); args->next->string = strdup("bar"); args->next->next = NULL; char *res = replace_m4(orig1, args); ck_assert_ptr_nonnull(res); ck_assert_str_eq("foo_t", res); free(res); const char *orig2 = "$2"; res = replace_m4(orig2, args); ck_assert_ptr_nonnull(res); ck_assert_str_eq("bar", res); free(res); const char *orig3 = "test_$1_test"; res = replace_m4(orig3, args); ck_assert_ptr_nonnull(res); ck_assert_str_eq("test_foo_test", res); free(res); const char *orig4 = "test$2$1"; res = replace_m4(orig4, args); ck_assert_ptr_nonnull(res); ck_assert_str_eq("testbarfoo", res); free(res); free_string_list(args); } END_TEST START_TEST (test_replace_m4_too_few_args) { struct string_list *args = calloc(1,sizeof(struct string_list)); args->string = strdup("foo"); args->next = calloc(1,sizeof(struct string_list)); args->next->string = strdup("bar"); args->next->next = NULL; const char *orig = "$3_t"; char *ret = replace_m4(orig, args); ck_assert_ptr_nonnull(ret); ck_assert_str_eq("_t", ret); free_string_list(args); free(ret); } END_TEST START_TEST (test_replace_m4_nothing_to_replace) { struct string_list *args = calloc(1, sizeof(struct string_list)); args->string = strdup("foo"); const char *orig = "bar_t"; char *res = replace_m4(orig, args); ck_assert_ptr_nonnull(res); ck_assert_str_eq("bar_t", res); free(res); free_string_list(args); } END_TEST START_TEST (test_replace_m4_bad_dollar_sign) { struct string_list *args = calloc(1, sizeof(struct string_list)); args->string = strdup("foo"); const char *orig = "$string"; ck_assert_ptr_null(replace_m4(orig, args)); free_string_list(args); } END_TEST START_TEST (test_replace_m4_list) { struct string_list *caller_args = calloc(1,sizeof(struct string_list)); caller_args->string = strdup("foo"); caller_args->next = calloc(1,sizeof(struct string_list)); caller_args->next->string = strdup("bar"); caller_args->next->next = NULL; struct string_list *called_args = calloc(1,sizeof(struct string_list)); called_args->string = strdup("$2"); called_args->next = calloc(1,sizeof(struct string_list)); called_args->next->string = strdup("$1"); called_args->next->next = NULL; struct string_list *ret = replace_m4_list(caller_args, called_args); ck_assert_ptr_nonnull(ret); ck_assert_str_eq(ret->string, "bar"); ck_assert_ptr_nonnull(ret->next); ck_assert_str_eq(ret->next->string, "foo"); ck_assert_ptr_null(ret->next->next); free_string_list(caller_args); free_string_list(called_args); free_string_list(ret); } END_TEST START_TEST (test_replace_m4_list_too_few_args) { struct string_list *caller_args = calloc(1,sizeof(struct string_list)); caller_args->string = strdup("foo"); struct string_list *called_args = calloc(1,sizeof(struct string_list)); called_args->string = strdup("$5"); struct string_list *ret = replace_m4_list(caller_args, called_args); ck_assert_ptr_nonnull(ret); ck_assert_ptr_nonnull(ret->string); ck_assert_str_eq("", ret->string); free_string_list(caller_args); free_string_list(called_args); free_string_list(ret); } END_TEST START_TEST (test_nested_template_declarations) { set_current_module_name("nested"); FILE *f = fopen(NESTED_IF_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, NESTED_IF_FILENAME, NODE_IF_FILE); ck_assert_ptr_nonnull(ast); fclose(f); struct string_list *called_args = calloc(1,sizeof(struct string_list)); called_args->string = strdup("first"); called_args->next = calloc(1,sizeof(struct string_list)); called_args->next->string = strdup("second"); called_args->next->next = calloc(1,sizeof(struct string_list)); called_args->next->next->string = strdup("third"); called_args->next->next->next = NULL; ck_assert_int_eq(SELINT_SUCCESS, add_template_declarations("outer", called_args, NULL, "nested_interfaces")); ck_assert_str_eq("nested_interfaces", look_up_in_decl_map("first_t", DECL_TYPE)); ck_assert_str_eq("nested_interfaces", look_up_in_decl_map("third_foo_t", DECL_TYPE)); ck_assert_str_eq("nested_interfaces", look_up_in_decl_map("second_bar_t", DECL_TYPE)); ck_assert_ptr_null(look_up_in_decl_map("second_foo_t", DECL_TYPE)); ck_assert_ptr_null(look_up_in_decl_map("third_bar_t", DECL_TYPE)); free_string_list(called_args); free_policy_node(ast); cleanup_parsing(); } END_TEST START_TEST (test_declaring_template) { // setup set_current_module_name("declaring_template_if"); FILE *f_if = fopen(DECLARING_IF_FILENAME, "r"); ck_assert_ptr_nonnull(f_if); struct policy_node *ast_if = yyparse_wrapper(f_if, DECLARING_IF_FILENAME, NODE_IF_FILE); ck_assert_ptr_nonnull(ast_if); fclose(f_if); set_current_module_name("declaring_template_te"); FILE *f_te = fopen(DECLARING_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f_te); struct policy_node *ast_te = yyparse_wrapper(f_te, DECLARING_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast_te); fclose(f_te); // checks const char *mod_name; ck_assert_uint_eq(6, decl_map_count(DECL_TYPE)); mod_name = look_up_in_decl_map("prefix_foo_suffix", DECL_TYPE); ck_assert_str_eq("declaring_template_te", mod_name); mod_name = look_up_in_decl_map("bar_t", DECL_TYPE); ck_assert_str_eq("declaring_template_te", mod_name); mod_name = look_up_in_decl_map("prefix_good_suffix", DECL_TYPE); ck_assert_str_eq("declaring_template_te", mod_name); mod_name = look_up_in_decl_map("morning_t", DECL_TYPE); ck_assert_str_eq("declaring_template_te", mod_name); // these are called via an interface so the mod_name is wrong mod_name = look_up_in_decl_map("prefix_hello_suffix", DECL_TYPE); ck_assert_str_eq("declaring_template_if", mod_name); mod_name = look_up_in_decl_map("world_t", DECL_TYPE); ck_assert_str_eq("declaring_template_if", mod_name); ck_assert_uint_eq(3, decl_map_count(DECL_ROLE)); mod_name = look_up_in_decl_map("bar_r", DECL_ROLE); ck_assert_str_eq("declaring_template_te", mod_name); mod_name = look_up_in_decl_map("morning_r", DECL_ROLE); ck_assert_str_eq("declaring_template_te", mod_name); // this is called via an interface so the mod_name is wrong mod_name = look_up_in_decl_map("world_t", DECL_TYPE); ck_assert_str_eq("declaring_template_if", mod_name); // cleanup free_policy_node(ast_te); free_policy_node(ast_if); cleanup_parsing(); } END_TEST static Suite *template_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Template"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_replace_m4); tcase_add_test(tc_core, test_replace_m4_too_few_args); tcase_add_test(tc_core, test_replace_m4_nothing_to_replace); tcase_add_test(tc_core, test_replace_m4_bad_dollar_sign); tcase_add_test(tc_core, test_replace_m4_list); tcase_add_test(tc_core, test_replace_m4_list_too_few_args); tcase_add_test(tc_core, test_nested_template_declarations); tcase_add_test(tc_core, test_declaring_template); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = template_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_check_hooks.c0000644000175100001710000001652614167117255014675 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "../src/check_hooks.h" int check_called; int check2_called; struct check_result * example_check(const struct check_data *check_data, const struct policy_node *node); struct check_result * example_check2(const struct check_data *check_data, const struct policy_node *node); struct check_result * returns_blank_result(const struct check_data *check_data, const struct policy_node *node); struct check_result * example_check(__attribute__((unused)) const struct check_data *check_data, __attribute__((unused)) const struct policy_node *node) { check_called = 1; return (struct check_result *) NULL; } struct check_result * example_check2(__attribute__((unused)) const struct check_data *check_data, __attribute__((unused)) const struct policy_node *node) { check2_called = 1; return (struct check_result *) NULL; } struct check_result * returns_blank_result(__attribute__((unused)) const struct check_data *check_data, __attribute__((unused)) const struct policy_node *node) { return calloc(1, sizeof(struct check_result)); } START_TEST (test_add_check) { struct checks *ck = calloc(1, sizeof(struct checks)); check_called = 0; ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_AV_RULE, ck, "E-999", example_check)); ck_assert_ptr_nonnull(ck->check_nodes[NODE_AV_RULE]); ck_assert_ptr_null(ck->check_nodes[NODE_FC_ENTRY]); ck_assert_ptr_null(ck->check_nodes[NODE_ERROR]); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_TT_RULE, ck, "E-999", example_check)); ck_assert_ptr_nonnull(ck->check_nodes[NODE_AV_RULE]); ck_assert_ptr_nonnull(ck->check_nodes[NODE_TT_RULE]); ck_assert_ptr_null(ck->check_nodes[NODE_FC_ENTRY]); ck_assert_ptr_null(ck->check_nodes[NODE_ERROR]); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_DECL, ck, "E-999", example_check)); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_INTERFACE_DEF, ck, "E-999", example_check)); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_TEMP_DEF, ck, "E-999", example_check)); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_IF_CALL, ck, "E-999", example_check)); ck_assert_ptr_nonnull(ck->check_nodes[NODE_DECL]); ck_assert_ptr_nonnull(ck->check_nodes[NODE_INTERFACE_DEF]); ck_assert_ptr_nonnull(ck->check_nodes[NODE_TEMP_DEF]); ck_assert_ptr_nonnull(ck->check_nodes[NODE_IF_CALL]); ck_assert_ptr_null(ck->check_nodes[NODE_FC_ENTRY]); ck_assert_ptr_null(ck->check_nodes[NODE_ERROR]); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_FC_ENTRY, ck, "E-999", example_check)); ck_assert_ptr_nonnull(ck->check_nodes[NODE_AV_RULE]); ck_assert_ptr_nonnull(ck->check_nodes[NODE_FC_ENTRY]); ck_assert_ptr_null(ck->check_nodes[NODE_ERROR]); ck_assert_ptr_eq(ck->check_nodes[NODE_FC_ENTRY]->check_function, example_check); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_ERROR, ck, "E-999", example_check)); ck_assert_ptr_nonnull(ck->check_nodes[NODE_ERROR]); ck_assert_int_eq(0, check_called); free_checks(ck); } END_TEST START_TEST (test_call_checks) { struct checks *ck = malloc(sizeof(struct checks)); memset(ck, 0, sizeof(struct checks)); check_called = 0; check2_called = 0; ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_AV_RULE, ck, "E-999", example_check)); struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_AV_RULE; ck_assert_int_eq(SELINT_SUCCESS, call_checks(ck, NULL, node)); ck_assert_int_eq(1, check_called); ck_assert_int_eq(0, check2_called); check_called = 0; ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_AV_RULE, ck, "E-999", example_check2)); ck_assert_int_eq(SELINT_SUCCESS, call_checks(ck, NULL, node)); ck_assert_int_eq(0, ck->check_nodes[NODE_AV_RULE]->issues_found); ck_assert_int_eq(0, ck->check_nodes[NODE_AV_RULE]->next->issues_found); ck_assert_int_eq(1, check_called); ck_assert_int_eq(1, check2_called); node->flavor = NODE_TT_RULE; check_called = 0; check2_called = 0; ck_assert_int_eq(SELINT_SUCCESS, call_checks(ck, NULL, node)); ck_assert_int_eq(0, ck->check_nodes[NODE_AV_RULE]->issues_found); ck_assert_int_eq(0, ck->check_nodes[NODE_AV_RULE]->next->issues_found); ck_assert_int_eq(0, check_called); ck_assert_int_eq(0, check2_called); free_policy_node(node); free_checks(ck); } END_TEST START_TEST (test_disable_check) { struct checks *ck = calloc(1, sizeof(struct checks)); check_called = 0; ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_AV_RULE, ck, "E-999", example_check)); struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_AV_RULE; ck_assert_int_eq(SELINT_SUCCESS, call_checks(ck, NULL, node)); ck_assert_int_eq(1, check_called); check_called = 0; node->exceptions = strdup("E-999\n"); ck_assert_int_eq(SELINT_SUCCESS, call_checks(ck, NULL, node)); ck_assert_int_eq(0, check_called); free_policy_node(node); free_checks(ck); } END_TEST START_TEST (test_is_valid_check) { ck_assert_int_eq(1, is_valid_check("W-001")); ck_assert_int_eq(1, is_valid_check("W-005")); ck_assert_int_eq(0, is_valid_check("W-107")); ck_assert_int_eq(0, is_valid_check("foobar")); ck_assert_int_eq(1, is_valid_check("C-001")); ck_assert_int_eq(1, is_valid_check("S-001")); ck_assert_int_eq(1, is_valid_check("E-001")); ck_assert_int_eq(1, is_valid_check("F-001")); ck_assert_int_eq(0, is_valid_check("X-001")); ck_assert_int_eq(0, is_valid_check("C-101")); } END_TEST START_TEST (test_increment_issues) { struct checks *ck = calloc(1, sizeof(struct checks)); ck_assert_int_eq(SELINT_SUCCESS, add_check(NODE_AV_RULE, ck, "E-999", returns_blank_result)); struct check_data *data = calloc(1, sizeof(struct check_data)); data->filename = strdup("example.te"); ck_assert_int_eq(0, ck->check_nodes[NODE_AV_RULE]->issues_found); struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_AV_RULE; ck_assert_int_eq(SELINT_SUCCESS, call_checks(ck, data, node)); ck_assert_int_eq(1, ck->check_nodes[NODE_AV_RULE]->issues_found); ck_assert_int_eq(SELINT_SUCCESS, call_checks(ck, data, node)); ck_assert_int_eq(2, ck->check_nodes[NODE_AV_RULE]->issues_found); free_policy_node(node); free(data->filename); free(data); free_checks(ck); } END_TEST static Suite *check_hooks_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Check_hooks"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_add_check); tcase_add_test(tc_core, test_call_checks); tcase_add_test(tc_core, test_disable_check); tcase_add_test(tc_core, test_is_valid_check); tcase_add_test(tc_core, test_increment_issues); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = check_hooks_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_parse_fc.c0000644000175100001710000001544214167117255014173 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "../src/tree.h" #include "../src/parse_fc.h" #define POLICIES_DIR SAMPLE_POL_DIR #define BASIC_FC_FILENAME POLICIES_DIR "basic.fc" #define WITH_M4_FILENAME POLICIES_DIR "with_m4.fc" #define NONE_CONTEXT_FILENAME POLICIES_DIR "none_context.fc" START_TEST (test_parse_context) { char context_str[] = "staff_u:staff_r:foo_t"; struct sel_context *ctx = parse_context(context_str); ck_assert_ptr_nonnull(ctx); ck_assert_str_eq("staff_u", ctx->user); ck_assert_str_eq("staff_r", ctx->role); ck_assert_str_eq("foo_t", ctx->type); ck_assert_ptr_null(ctx->range); ck_assert_int_eq(0, ctx->has_gen_context); free_sel_context(ctx); } END_TEST START_TEST (test_parse_context_missing_field) { char context_str[] = "staff_u:foo_t"; struct sel_context *ctx = parse_context(context_str); ck_assert_ptr_null(ctx); } END_TEST START_TEST (test_parse_fc_line_with_gen_context) { char line[] = "/usr/bin(/.*)? gen_context(system_u:object_r:bin_t, s0)"; struct fc_entry *out= parse_fc_line(line); ck_assert_ptr_nonnull(out); ck_assert_str_eq("/usr/bin(/.*)?", out->path); ck_assert(out->obj == '\0'); ck_assert_ptr_nonnull(out->context); ck_assert_int_eq(1, out->context->has_gen_context); ck_assert_str_eq("system_u", out->context->user); ck_assert_str_eq("object_r", out->context->role); ck_assert_str_eq("bin_t", out->context->type); ck_assert_str_eq("s0", out->context->range); free_fc_entry(out); char line2[] = "/usr/bin(/.*)? gen_context(system_u:object_r:bin_t)"; out= parse_fc_line(line2); ck_assert_ptr_nonnull(out); ck_assert_str_eq("/usr/bin(/.*)?", out->path); ck_assert(out->obj == '\0'); ck_assert_ptr_nonnull(out->context); ck_assert_int_eq(1, out->context->has_gen_context); ck_assert_str_eq("system_u", out->context->user); ck_assert_str_eq("object_r", out->context->role); ck_assert_str_eq("bin_t", out->context->type); ck_assert_ptr_null(out->context->range); free_fc_entry(out); } END_TEST START_TEST (test_parse_fc_line) { char line[] = "/usr/bin(/.*)? system_u:object_r:bin_t:s0"; struct fc_entry *out= parse_fc_line(line); ck_assert_ptr_nonnull(out); ck_assert_str_eq("/usr/bin(/.*)?", out->path); ck_assert(out->obj == '\0'); ck_assert_ptr_nonnull(out->context); ck_assert_int_eq(0, out->context->has_gen_context); ck_assert_str_eq("system_u", out->context->user); ck_assert_str_eq("object_r", out->context->role); ck_assert_str_eq("bin_t", out->context->type); ck_assert_str_eq("s0", out->context->range); free_fc_entry(out); } END_TEST START_TEST (test_parse_fc_line_with_obj) { char line[] = "/usr/bin(/.*)? -d system_u:object_r:bin_t:s0"; struct fc_entry *out= parse_fc_line(line); ck_assert_ptr_nonnull(out); ck_assert_str_eq("/usr/bin(/.*)?", out->path); ck_assert(out->obj == 'd'); ck_assert_ptr_nonnull(out->context); ck_assert_int_eq(0, out->context->has_gen_context); ck_assert_str_eq("system_u", out->context->user); ck_assert_str_eq("object_r", out->context->role); ck_assert_str_eq("bin_t", out->context->type); ck_assert_str_eq("s0", out->context->range); free_fc_entry(out); } END_TEST START_TEST (test_parse_basic_fc_file) { struct policy_node *ast = parse_fc_file(BASIC_FC_FILENAME, NULL); ck_assert_ptr_nonnull(ast); ck_assert_int_eq(ast->flavor, NODE_FC_FILE); ck_assert_ptr_nonnull(ast->next); struct policy_node *cur = ast->next; ck_assert_int_eq(cur->flavor, NODE_FC_ENTRY); ck_assert_ptr_nonnull(cur->next); cur = cur->next; ck_assert_int_eq(cur->flavor, NODE_FC_ENTRY); ck_assert_ptr_nonnull(cur->next); cur = cur->next; ck_assert_int_eq(cur->flavor, NODE_ERROR); ck_assert_ptr_nonnull(cur->next); cur = cur->next; ck_assert_int_eq(cur->flavor, NODE_FC_ENTRY); ck_assert_ptr_nonnull(cur->next); cur = cur->next; ck_assert_int_eq(cur->flavor, NODE_FC_ENTRY); ck_assert_ptr_null(cur->next); free_policy_node(ast); } END_TEST START_TEST (test_parse_m4) { struct policy_node *ast = parse_fc_file(WITH_M4_FILENAME, NULL); ck_assert_ptr_nonnull(ast); ck_assert_int_eq(ast->flavor, NODE_FC_FILE); ck_assert_ptr_nonnull(ast->next); struct policy_node *cur = ast->next; ck_assert_int_eq(cur->flavor, NODE_FC_ENTRY); ck_assert_ptr_nonnull(cur->next); cur = cur->next; ck_assert_int_eq(cur->flavor, NODE_FC_ENTRY); ck_assert_ptr_nonnull(cur->data.fc_data); struct fc_entry *data = cur->data.fc_data; ck_assert_ptr_nonnull(data->context); ck_assert_str_eq(data->context->type, "hijklmn_t"); ck_assert_ptr_null(cur->next); free_policy_node(ast); } END_TEST START_TEST (test_parse_none_context) { struct policy_node *ast = parse_fc_file(NONE_CONTEXT_FILENAME, NULL); ck_assert_ptr_nonnull(ast); ck_assert_int_eq(ast->flavor, NODE_FC_FILE); ck_assert_ptr_nonnull(ast->next); struct policy_node *cur = ast->next; ck_assert_int_eq(cur->flavor, NODE_FC_ENTRY); ck_assert_ptr_null(cur->next); struct fc_entry *data = cur->data.fc_data; ck_assert_ptr_null(data->context); free_policy_node(ast); } END_TEST START_TEST (test_check_for_fc_macro) { ck_assert_int_eq(0, check_for_fc_macro("foo(`bar')", NULL)); struct string_list *cfm = calloc(1, sizeof(struct string_list)); cfm->string = strdup("foo"); ck_assert_int_eq(1, check_for_fc_macro("foo(`bar')", cfm)); ck_assert_int_eq(0, check_for_fc_macro("baz(`bar')", cfm)); ck_assert_int_eq(0, check_for_fc_macro("a", cfm)); free_string_list(cfm); } END_TEST static Suite *parse_fc_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Parse_fc"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_parse_context); tcase_add_test(tc_core, test_parse_context_missing_field); tcase_add_test(tc_core, test_parse_fc_line_with_gen_context); tcase_add_test(tc_core, test_parse_fc_line); tcase_add_test(tc_core, test_parse_fc_line_with_obj); tcase_add_test(tc_core, test_parse_basic_fc_file); tcase_add_test(tc_core, test_parse_m4); tcase_add_test(tc_core, test_parse_none_context); tcase_add_test(tc_core, test_check_for_fc_macro); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = parse_fc_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/test_utils.c0000644000175100001710000000526514167117255013455 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "test_utils.h" struct av_rule_data * make_example_av_rule() { // allow foo_t { bar_t baz_t }:file { read write getattr }; struct av_rule_data *av_rule_data = malloc(sizeof(struct av_rule_data)); av_rule_data->flavor = AV_RULE_ALLOW; av_rule_data->sources = calloc(1,sizeof(struct string_list)); ck_assert_ptr_nonnull(av_rule_data->sources); av_rule_data->sources->string = strdup(EXAMPLE_TYPE_1); ck_assert_ptr_nonnull(av_rule_data->sources->string); av_rule_data->sources->next = NULL; av_rule_data->targets = calloc(1,sizeof(struct string_list)); ck_assert_ptr_nonnull(av_rule_data->targets); av_rule_data->targets->string = strdup(EXAMPLE_TYPE_2); ck_assert_ptr_nonnull(av_rule_data->targets->string); av_rule_data->targets->next = calloc(1,sizeof(struct string_list)); ck_assert_ptr_nonnull(av_rule_data->targets->next); av_rule_data->targets->next->string = strdup(EXAMPLE_TYPE_3); ck_assert_ptr_nonnull(av_rule_data->targets->next->string); av_rule_data->targets->next->next = NULL; av_rule_data->object_classes = calloc(1,sizeof(struct string_list)); ck_assert_ptr_nonnull(av_rule_data->object_classes); av_rule_data->object_classes->string = strdup("file"); ck_assert_ptr_nonnull(av_rule_data->object_classes->string); av_rule_data->object_classes->next = NULL; av_rule_data->perms = calloc(1,sizeof(struct string_list)); ck_assert_ptr_nonnull(av_rule_data->perms); av_rule_data->perms->string = strdup("read"); ck_assert_ptr_nonnull(av_rule_data->perms->string); av_rule_data->perms->next = calloc(1,sizeof(struct string_list)); ck_assert_ptr_nonnull(av_rule_data->perms->next); av_rule_data->perms->next->string = strdup("write"); ck_assert_ptr_nonnull(av_rule_data->perms->next->string); av_rule_data->perms->next->next = calloc(1,sizeof(struct string_list)); ck_assert_ptr_nonnull(av_rule_data->perms->next->next); av_rule_data->perms->next->next->string = strdup("getattr"); ck_assert_ptr_nonnull(av_rule_data->perms->next->next->string); av_rule_data->perms->next->next->next = NULL; return av_rule_data; } selint-1.2.1/tests/check_startup.c0000644000175100001710000001102414167117255014103 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "../src/startup.h" #include "../src/maps.h" #include "../src/selint_error.h" #include "../src/parse_functions.h" #define MODULES_CONF_PATH SAMPLE_POL_DIR "modules.conf" #define BAD_MODULES_CONF_PATH SAMPLE_POL_DIR "bad_modules.conf" #define OBJ_PERM_SETS_PATH SAMPLE_POL_DIR "obj_perm_sets.spt" #define BAD_OBJ_PERM_SETS_PATH SAMPLE_POL_DIR "bad_obj_perm_sets.spt" #define SAMPLE_AV_PATH SAMPLE_AV_DIR #define ACCESS_VECTORS_PATH SAMPLE_POL_DIR "access_vectors" START_TEST (test_load_access_vectors_kernel) { ck_assert_int_eq(load_access_vectors_kernel(SAMPLE_AV_PATH), SELINT_SUCCESS); ck_assert_int_eq(decl_map_count(DECL_CLASS), 3); ck_assert_int_eq(decl_map_count(DECL_PERM), 37); ck_assert_str_eq(look_up_in_decl_map("file", DECL_CLASS), "class"); ck_assert_str_eq(look_up_in_decl_map("append", DECL_PERM), "perm"); ck_assert_str_eq(look_up_in_decl_map("listen", DECL_PERM), "perm"); ck_assert_str_eq(look_up_in_decl_map("use", DECL_PERM), "perm"); free_all_maps(); } END_TEST START_TEST (test_load_access_vectors_source) { ck_assert_int_eq(load_access_vectors_source(ACCESS_VECTORS_PATH), SELINT_SUCCESS); ck_assert_int_eq(decl_map_count(DECL_CLASS), 8); ck_assert_int_eq(decl_map_count(DECL_PERM), 33); ck_assert_str_eq(look_up_in_decl_map("file", DECL_CLASS), "__av_file__"); ck_assert_str_eq(look_up_in_decl_map("append", DECL_PERM), "__av_file__"); ck_assert_str_eq(look_up_in_decl_map("use", DECL_PERM), "__av_file__"); free_all_maps(); } END_TEST START_TEST (test_load_modules_source) { enum selint_error res = load_modules_source(MODULES_CONF_PATH); ck_assert_int_eq(SELINT_SUCCESS, res); ck_assert_str_eq("base", look_up_in_mods_map("sysadm")); ck_assert_str_eq("module", look_up_in_mods_map("sudo")); ck_assert_str_eq("off", look_up_in_mods_map("games")); res = load_modules_source(BAD_MODULES_CONF_PATH); ck_assert_int_eq(SELINT_PARSE_ERROR, res); free_all_maps(); } END_TEST START_TEST (test_load_obj_perm_sets_source) { enum selint_error res = load_obj_perm_sets_source(OBJ_PERM_SETS_PATH); ck_assert_int_eq(SELINT_SUCCESS, res); const struct string_list *mount_fs_perms = look_up_in_permmacros_map("mount_fs_perms"); ck_assert_ptr_nonnull(mount_fs_perms); ck_assert_int_eq(1, str_in_sl("mount", mount_fs_perms)); ck_assert_int_eq(1, str_in_sl("remount", mount_fs_perms)); ck_assert_int_eq(1, str_in_sl("unmount", mount_fs_perms)); ck_assert_int_eq(1, str_in_sl("getattr", mount_fs_perms)); ck_assert_int_eq(0, str_in_sl("search", mount_fs_perms)); const struct string_list *rw_socket_perms = look_up_in_permmacros_map("rw_socket_perms"); ck_assert_ptr_nonnull(rw_socket_perms); ck_assert_int_eq(1, str_in_sl("ioctl", rw_socket_perms)); ck_assert_int_eq(1, str_in_sl("getattr", rw_socket_perms)); ck_assert_int_eq(1, str_in_sl("setattr", rw_socket_perms)); ck_assert_int_eq(1, str_in_sl("bind", rw_socket_perms)); ck_assert_int_eq(1, str_in_sl("getopt", rw_socket_perms)); ck_assert_int_eq(1, str_in_sl("shutdown", rw_socket_perms)); ck_assert_int_eq(0, str_in_sl("admin", rw_socket_perms)); ck_assert_ptr_null(look_up_in_permmacros_map("dir_file_class_set")); ck_assert_ptr_null(look_up_in_permmacros_map("remount_fs_perms")); res = load_obj_perm_sets_source(BAD_OBJ_PERM_SETS_PATH); ck_assert_int_eq(SELINT_PARSE_ERROR, res); cleanup_parsing(); } END_TEST static Suite *startup_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Startup"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_load_access_vectors_kernel); tcase_add_test(tc_core, test_load_access_vectors_source); tcase_add_test(tc_core, test_load_modules_source); tcase_add_test(tc_core, test_load_obj_perm_sets_source); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = startup_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_te_checks.c0000644000175100001710000002045114167117255014335 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "test_utils.h" #include "../src/te_checks.h" #include "../src/check_hooks.h" #include "../src/maps.h" START_TEST (test_check_te_order) { struct check_data *cd = calloc(1, sizeof(struct check_data)); cd->flavor = FILE_TE_FILE; struct config_check_data *ccd = calloc(1, sizeof(struct config_check_data)); ccd->order_conf = ORDER_REF; cd->config_check_data = ccd; struct policy_node *head = calloc(1, sizeof(struct policy_node)); head->flavor = NODE_TE_FILE; head->next = calloc(1, sizeof(struct policy_node)); struct policy_node *cur = head->next; cur->flavor = NODE_DECL; cur->data.d_data = calloc(1, sizeof(struct declaration_data)); cur->data.d_data->flavor = DECL_TYPE; cur->data.d_data->name = strdup("foo_t"); cur->next = calloc(1, sizeof(struct policy_node)); cur = cur->next; cur->flavor = NODE_IF_CALL; cur->data.ic_data = calloc(1, sizeof(struct if_call_data)); cur->data.ic_data->name = strdup("domain_type"); cur->data.ic_data->args = calloc(1, sizeof(struct string_list)); cur->data.ic_data->args->string = strdup("foo_t"); mark_transform_if("domain_type"); cur->next = calloc(1, sizeof(struct policy_node)); cur = cur->next; cur->flavor = NODE_AV_RULE; cur->data.av_data = make_example_av_rule(); cur = head; while (cur) { ck_assert_ptr_null(check_te_order(cd, cur)); cur = dfs_next(cur); } struct policy_node *cleanup = calloc(1, sizeof(struct policy_node)); cleanup->flavor = NODE_CLEANUP; ck_assert_ptr_null(check_te_order(cd, cleanup)); free(ccd); free(cd); free_policy_node(head); free_policy_node(cleanup); free_all_maps(); } END_TEST START_TEST (test_check_require_block) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_REQUIRE; struct check_data *cd = calloc(1, sizeof(struct check_data)); cd->flavor = FILE_IF_FILE; ck_assert_ptr_null(check_require_block(cd, cur)); cd->flavor = FILE_FC_FILE; ck_assert_ptr_null(check_require_block(cd, cur)); cd->flavor = FILE_TE_FILE; cur->first_child = calloc(1, sizeof(struct policy_node)); cur->first_child->flavor = NODE_DECL; cur->first_child->data.d_data = calloc(1, sizeof(struct declaration_data)); cur->first_child->data.d_data->flavor = DECL_TYPE; struct check_result *res = check_require_block(cd, cur); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'S'); ck_assert_int_eq(res->check_id, S_ID_REQUIRE); free_check_result(res); cur->flavor = NODE_GEN_REQ; res = check_require_block(cd, cur); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'S'); ck_assert_int_eq(res->check_id, S_ID_REQUIRE); free_check_result(res); free(cd); free_policy_node(cur); } END_TEST START_TEST (test_check_useless_semicolon) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_SEMICOLON; struct check_data *cd = calloc(1, sizeof(struct check_data)); struct check_result *res = check_useless_semicolon(cd, cur); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'S'); ck_assert_int_eq(res->check_id, S_ID_SEMICOLON); free_check_result(res); free(cd); free_policy_node(cur); } END_TEST START_TEST (test_check_no_explicit_declaration) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); struct check_data *cd = calloc(1, sizeof(struct check_data)); cur->flavor = NODE_AV_RULE; cur->data.av_data = make_example_av_rule(); cd->flavor = FILE_IF_FILE; cd->mod_name = strdup("foo"); ck_assert_ptr_null(check_no_explicit_declaration(cd, cur)); cd->flavor = FILE_TE_FILE; // If the type isn't found, we don't do anything ck_assert_ptr_null(check_no_explicit_declaration(cd, cur)); insert_into_decl_map("foo_t", "foo", DECL_TYPE); insert_into_decl_map("other_t", "other", DECL_TYPE); ck_assert_ptr_null(check_no_explicit_declaration(cd, cur)); insert_into_decl_map("bar_t", "bar", DECL_TYPE); struct check_result *res = check_no_explicit_declaration(cd, cur); ck_assert_ptr_nonnull(res); ck_assert_int_eq(W_ID_NO_EXPLICIT_DECL, res->check_id); free_check_result(res); // Require block cur->prev = calloc(1, sizeof(struct policy_node)); cur->prev->next = cur; cur = cur->prev; cur->flavor = NODE_REQUIRE; union node_data nd; nd.d_data = NULL; ck_assert_int_eq(SELINT_SUCCESS, insert_policy_node_child(cur, NODE_START_BLOCK, nd, 0)); nd.d_data = calloc(1, sizeof(struct declaration_data)); nd.d_data->flavor = DECL_TYPE; nd.d_data->name = strdup("bar_t"); ck_assert_int_eq(SELINT_SUCCESS, insert_policy_node_child(cur, NODE_DECL, nd, 0)); ck_assert_ptr_null(check_no_explicit_declaration(cd, cur->next)); cur->flavor = NODE_GEN_REQ; ck_assert_ptr_null(check_no_explicit_declaration(cd, cur->next)); free(cur->first_child->next->data.d_data->name); cur->first_child->next->data.d_data->name = strdup("baz_t"); res = check_no_explicit_declaration(cd, cur->next); ck_assert_ptr_nonnull(res); ck_assert_int_eq(W_ID_NO_EXPLICIT_DECL, res->check_id); free_check_result(res); free_all_maps(); free(cd->mod_name); free(cd); free_policy_node(cur); } END_TEST START_TEST (test_check_module_if_call_in_optional) { struct check_result *res; char *foo_read_str = strdup("foo_read"); char *bar_read_str = strdup("bar_read"); struct policy_node *cur = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_IF_CALL; struct if_call_data *ic_data = calloc(1, sizeof(struct if_call_data)); cur->data.ic_data = ic_data; ic_data->name = foo_read_str; struct check_data *cd = calloc(1, sizeof(struct check_data)); cd->mod_name = strdup("baz"); insert_into_ifs_map("foo_read", "foo"); insert_into_mods_map("foo", "module"); res = check_module_if_call_in_optional(cd, cur); ck_assert_ptr_nonnull(res); free_check_result(res); ic_data->name = bar_read_str; insert_into_ifs_map("bar_read", "bar"); insert_into_mods_map("bar", "base"); res = check_module_if_call_in_optional(cd, cur); ck_assert_ptr_null(res); cur->parent = calloc(1, sizeof(struct policy_node)); cur->parent->flavor = NODE_OPTIONAL_POLICY; cur->parent->first_child = cur; res = check_module_if_call_in_optional(cd, cur); ck_assert_ptr_null(res); ic_data->name = foo_read_str; res = check_module_if_call_in_optional(cd, cur); ck_assert_ptr_null(res); free(bar_read_str); free(cd->mod_name); free(cd); free_all_maps(); free_policy_node(cur->parent); } END_TEST START_TEST (test_check_attribute_interface_nameclash) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_DECL; node->data.d_data = calloc(1, sizeof(struct declaration_data)); node->data.d_data->flavor = DECL_ATTRIBUTE; node->data.d_data->name = strdup("foo"); ck_assert_ptr_null(check_declaration_interface_nameclash(NULL, node)); insert_into_ifs_map("foo", "bar"); struct check_result *res = check_declaration_interface_nameclash(NULL, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'E'); ck_assert_int_eq(res->check_id, E_ID_DECL_IF_CLASH); free_check_result(res); free_policy_node(node); free_all_maps(); } END_TEST static Suite *te_checks_suite(void) { Suite *s; TCase *tc_core; s = suite_create("TE_Checks"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_check_te_order); tcase_add_test(tc_core, test_check_require_block); tcase_add_test(tc_core, test_check_useless_semicolon); tcase_add_test(tc_core, test_check_no_explicit_declaration); tcase_add_test(tc_core, test_check_module_if_call_in_optional); tcase_add_test(tc_core, test_check_attribute_interface_nameclash); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = te_checks_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_file_list.c0000644000175100001710000000634014167117255014360 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "../src/file_list.h" # START_TEST (test_file_list_push_back) { struct policy_node *ast1 = malloc(sizeof(struct policy_node)); memset(ast1, 0, sizeof(struct policy_node)); struct policy_node *ast2 = malloc(sizeof(struct policy_node)); memset(ast2, 0, sizeof(struct policy_node)); struct policy_node *ast3 = malloc(sizeof(struct policy_node)); memset(ast3, 0, sizeof(struct policy_node)); struct policy_node *ast4 = malloc(sizeof(struct policy_node)); memset(ast4, 0, sizeof(struct policy_node)); struct policy_file_list *list = malloc(sizeof(struct policy_file_list)); memset(list, 0, sizeof(struct policy_file_list)); file_list_push_back(list, make_policy_file("file1", ast1)); file_list_push_back(list, make_policy_file("file2", ast2)); file_list_push_back(list, make_policy_file("file3", ast3)); file_list_push_back(list, make_policy_file("file4", ast4)); ck_assert_ptr_eq(list->head->file->ast, ast1); ck_assert_str_eq(list->head->file->filename, "file1"); ck_assert_ptr_eq(list->head->next->file->ast, ast2); ck_assert_str_eq(list->head->next->file->filename, "file2"); ck_assert_ptr_eq(list->tail->file->ast, ast4); ck_assert_str_eq(list->tail->file->filename, "file4"); free_file_list(list); } END_TEST START_TEST (test_make_policy_file) { struct policy_file *file = make_policy_file("foo", NULL); ck_assert_ptr_nonnull(file); ck_assert_str_eq(file->filename, "foo"); ck_assert_ptr_null(file->ast); free(file->filename); free(file); } END_TEST START_TEST (test_file_name_in_file_list) { struct policy_file_list *list = calloc(1, sizeof(struct policy_file_list)); file_list_push_back(list, make_policy_file("foo", NULL)); file_list_push_back(list, make_policy_file("bar", NULL)); file_list_push_back(list, make_policy_file("baz", NULL)); ck_assert_int_eq(0, file_name_in_file_list("not_in_list", list)); ck_assert_int_eq(1, file_name_in_file_list("foo", list)); ck_assert_int_eq(1, file_name_in_file_list("bar", list)); ck_assert_int_eq(1, file_name_in_file_list("baz", list)); free_file_list(list); } END_TEST static Suite *file_list_suite(void) { Suite *s; TCase *tc_core; s = suite_create("File List"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_file_list_push_back); tcase_add_test(tc_core, test_make_policy_file); tcase_add_test(tc_core, test_file_name_in_file_list); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = file_list_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_tree.c0000644000175100001710000001707214167117255013351 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "test_utils.h" #include "../src/tree.h" #include "../src/maps.h" START_TEST (test_insert_policy_node_child) { struct policy_node parent_node; parent_node.parent = NULL; parent_node.next = NULL; parent_node.prev = NULL; parent_node.first_child = NULL; parent_node.flavor = NODE_TE_FILE; parent_node.data.str = NULL; union node_data nd; nd.av_data = make_example_av_rule(); ck_assert_int_eq(SELINT_SUCCESS, insert_policy_node_child(&parent_node, NODE_AV_RULE, nd, 1234)); ck_assert_ptr_null(parent_node.next); ck_assert_ptr_nonnull(parent_node.first_child); ck_assert_ptr_eq(parent_node.first_child->data.av_data, nd.av_data); ck_assert_int_eq(parent_node.first_child->flavor, NODE_AV_RULE); ck_assert_int_eq(parent_node.first_child->lineno, 1234); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(parent_node.first_child)); } END_TEST START_TEST (test_insert_policy_node_next) { struct policy_node prev_node; prev_node.parent = NULL; prev_node.next = NULL; prev_node.prev = NULL; prev_node.first_child = NULL; prev_node.flavor = NODE_TE_FILE; prev_node.data.str = NULL; union node_data nd; nd.av_data = make_example_av_rule(); ck_assert_int_eq(SELINT_SUCCESS, insert_policy_node_next(&prev_node, NODE_AV_RULE, nd, 1234)); ck_assert_ptr_null(prev_node.first_child); ck_assert_ptr_nonnull(prev_node.next); ck_assert_ptr_eq(prev_node.next->data.av_data, nd.av_data); ck_assert_int_eq(prev_node.next->flavor, NODE_AV_RULE); ck_assert_int_eq(prev_node.next->lineno, 1234); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(prev_node.next)); } END_TEST START_TEST (test_is_template_call) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); ck_assert_int_eq(0, is_template_call(node)); struct if_call_data *data = calloc(1, sizeof(struct if_call_data)); data->name = strdup("foo"); node->data.ic_data = data; ck_assert_int_eq(0, is_template_call(node)); node->flavor = NODE_IF_CALL; ck_assert_int_eq(0, is_template_call(node)); insert_call_into_template_map("foo", data); ck_assert_int_eq(1, is_template_call(node)); free_policy_node(node); free_all_maps(); } END_TEST START_TEST (test_get_types_in_node_av) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_AV_RULE; node->data.av_data = make_example_av_rule(); struct string_list *out = get_names_in_node(node); struct string_list *cur = out; ck_assert_ptr_nonnull(cur); ck_assert_str_eq(cur->string, EXAMPLE_TYPE_1); cur = cur->next; ck_assert_ptr_nonnull(cur); ck_assert_str_eq(cur->string, EXAMPLE_TYPE_2); cur = cur->next; ck_assert_ptr_nonnull(cur); ck_assert_str_eq(cur->string, EXAMPLE_TYPE_3); ck_assert_ptr_null(cur->next); free_string_list(out); free_policy_node(node); } END_TEST START_TEST (test_get_types_in_node_tt) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_TT_RULE; node->data.tt_data = calloc(1, sizeof(struct type_transition_data)); struct type_transition_data *tt_data = (struct type_transition_data *)node->data.tt_data; tt_data->sources = calloc(1, sizeof(struct string_list)); tt_data->sources->string = strdup(EXAMPLE_TYPE_3); tt_data->targets = calloc(1, sizeof(struct string_list)); tt_data->targets->string = strdup(EXAMPLE_TYPE_2); tt_data->default_type = strdup(EXAMPLE_TYPE_1); struct string_list *out = get_names_in_node(node); struct string_list *cur = out; ck_assert_ptr_nonnull(cur); ck_assert_str_eq(cur->string, EXAMPLE_TYPE_3); cur = cur->next; ck_assert_ptr_nonnull(cur); ck_assert_str_eq(cur->string, EXAMPLE_TYPE_2); cur = cur->next; ck_assert_ptr_nonnull(cur); ck_assert_str_eq(cur->string, EXAMPLE_TYPE_1); ck_assert_ptr_null(cur->next); free_string_list(out); free_policy_node(node); } END_TEST START_TEST (test_get_types_in_node_dd) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_DECL; node->data.d_data = calloc(1, sizeof(struct declaration_data)); struct declaration_data *d_data = (struct declaration_data *)node->data.d_data; d_data->name = strdup(EXAMPLE_TYPE_2); struct string_list *out = get_names_in_node(node); ck_assert_ptr_nonnull(out); ck_assert_str_eq(out->string, EXAMPLE_TYPE_2); ck_assert_ptr_null(out->next); free_string_list(out); free_policy_node(node); } END_TEST START_TEST (test_get_types_in_node_if_call) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_IF_CALL; node->data.ic_data = calloc(1, sizeof(struct if_call_data)); struct if_call_data *if_data = (struct if_call_data *)node->data.ic_data; if_data->name = strdup("foo_read"); if_data->args = calloc(1, sizeof(struct string_list)); if_data->args->string = strdup("bar_t"); if_data->args->next = calloc(1, sizeof(struct string_list)); if_data->args->next->string = strdup("baz_t"); struct string_list *out = get_names_in_node(node); ck_assert_ptr_nonnull(out); ck_assert_str_eq(out->string, "bar_t"); ck_assert_str_eq(out->next->string, "baz_t"); ck_assert_ptr_null(out->next->next); free_string_list(out); free_policy_node(node); } END_TEST START_TEST (test_get_types_in_node_no_types) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_ERROR; ck_assert_ptr_null(get_names_in_node(node)); free_policy_node(node); } END_TEST START_TEST (test_get_types_in_node_exclusion) { struct policy_node *node = calloc(1, sizeof(struct policy_node)); node->flavor = NODE_AV_RULE; node->data.av_data = calloc(1, sizeof(struct av_rule_data)); node->data.av_data->sources = calloc(1, sizeof(struct string_list)); node->data.av_data->sources->string = strdup("domain"); node->data.av_data->sources->next = calloc(1, sizeof(struct string_list)); node->data.av_data->sources->next->string = strdup("-init_t"); struct string_list *out = get_names_in_node(node); ck_assert_ptr_nonnull(out); ck_assert_str_eq(out->string, "domain"); ck_assert_str_eq(out->next->string, "init_t"); // Strip "-" ck_assert_ptr_null(out->next->next); free_string_list(out); free_policy_node(node); } END_TEST static Suite *tree_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Tree"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_insert_policy_node_child); tcase_add_test(tc_core, test_insert_policy_node_next); tcase_add_test(tc_core, test_is_template_call); tcase_add_test(tc_core, test_get_types_in_node_av); tcase_add_test(tc_core, test_get_types_in_node_tt); tcase_add_test(tc_core, test_get_types_in_node_dd); tcase_add_test(tc_core, test_get_types_in_node_if_call); tcase_add_test(tc_core, test_get_types_in_node_no_types); tcase_add_test(tc_core, test_get_types_in_node_exclusion); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = tree_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_parsing.c0000644000175100001710000006605214167117255014057 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "../src/tree.h" #include "../src/parse.h" #include "../src/parse_functions.h" #define POLICIES_DIR SAMPLE_POL_DIR #define BASIC_TE_FILENAME POLICIES_DIR "basic.te" #define BASIC_IF_FILENAME POLICIES_DIR "basic.if" #define UNCOMMON_TE_FILENAME POLICIES_DIR "uncommon.te" #define BLOCKS_TE_FILENAME POLICIES_DIR "blocks.te" #define EMPTY_TE_FILENAME POLICIES_DIR "empty.te" #define SYNTAX_ERROR_FILENAME POLICIES_DIR "syntax_error.te" #define BAD_RA_FILENAME POLICIES_DIR "bad_role_allow.te" #define DISABLE_COMMENT_TE_FILENAME POLICIES_DIR "disable_comment.te" #define DISABLE_COMMENT_IF_FILENAME POLICIES_DIR "disable_comment.if" #define BOOL_DECLARATION_FILENAME POLICIES_DIR "bool_declarations.te" #define EXTENDED_TE_FILENAME POLICIES_DIR "extended_perms.te" #define IFDEF_BLOCK_FILENAME POLICIES_DIR "ifdef_block.te" START_TEST (test_parse_basic_te) { set_current_module_name("basic"); FILE *f = fopen(BASIC_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, BASIC_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast); struct policy_node *current = ast; ck_assert_ptr_nonnull(current); ck_assert_int_eq(NODE_TE_FILE, current->flavor); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = ast->next; ck_assert_int_eq(NODE_HEADER, current->flavor); struct header_data *hd = current->data.h_data; ck_assert_int_eq(HEADER_MACRO, hd->flavor); ck_assert_str_eq("basic", hd->module_name); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_DECL, current->flavor); struct declaration_data *dd = current->data.d_data; ck_assert_int_eq(DECL_TYPE, dd->flavor); ck_assert_str_eq("basic_t", dd->name); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_DECL, current->flavor); dd = current->data.d_data; ck_assert_int_eq(DECL_TYPE, dd->flavor); ck_assert_str_eq("basic_exec_t", dd->name); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_OPTIONAL_POLICY, current->flavor); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_nonnull(current->first_child); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_str_eq("basic", look_up_in_decl_map("basic_t", DECL_TYPE)); ck_assert_int_eq(2, decl_map_count(DECL_TYPE)); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_parse_basic_if) { set_current_module_name("basic"); FILE *f = fopen(BASIC_IF_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, BASIC_IF_FILENAME, NODE_IF_FILE); ck_assert_ptr_nonnull(ast); struct policy_node *current = ast; ck_assert_ptr_nonnull(current); ck_assert_int_eq(NODE_IF_FILE, current->flavor); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_COMMENT, current->flavor); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_COMMENT, current->flavor); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_INTERFACE_DEF, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_str_eq("basic_domtrans", current->data.str); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(current->flavor, NODE_GEN_REQ); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_nonnull(current->prev); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_DECL, current->flavor); ck_assert_str_eq("basic_t", current->data.d_data->name); ck_assert_ptr_null(current->first_child); ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_nonnull(current->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_DECL, current->flavor); ck_assert_str_eq("basic_exec_t", current->data.d_data->name); ck_assert_ptr_null(current->first_child); ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_nonnull(current->parent); ck_assert_ptr_null(current->next); current = current->parent->next; ck_assert_int_eq(NODE_IF_CALL, current->flavor); ck_assert_ptr_nonnull(current->parent); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_parse_uncommon_constructs) { set_current_module_name("uncommon"); FILE *f = fopen(UNCOMMON_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, UNCOMMON_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast); ck_assert_ptr_nonnull(ast); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_parse_blocks) { set_current_module_name("blocks"); FILE *f = fopen(BLOCKS_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, BLOCKS_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast); ck_assert_ptr_nonnull(ast); struct policy_node *current = ast; ck_assert_int_eq(NODE_TE_FILE, current->flavor); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_HEADER, current->flavor); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_OPTIONAL_POLICY, current->flavor); ck_assert_ptr_null(current->next); ck_assert_ptr_nonnull(current->first_child); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->next); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_parse_empty_file) { set_current_module_name("empty"); FILE *f = fopen(EMPTY_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, EMPTY_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast); ck_assert_int_eq(NODE_EMPTY, ast->flavor); ck_assert_ptr_null(ast->next); ck_assert_ptr_null(ast->first_child); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_syntax_error) { set_current_module_name("syntax_error"); FILE *f = fopen(SYNTAX_ERROR_FILENAME, "r"); ck_assert_ptr_nonnull(f); ck_assert_ptr_null(yyparse_wrapper(f, SYNTAX_ERROR_FILENAME, NODE_TE_FILE)); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_parse_bad_role_allow) { set_current_module_name("bad_ra"); FILE *f = fopen(BAD_RA_FILENAME, "r"); ck_assert_ptr_nonnull(f); ck_assert_ptr_null(yyparse_wrapper(f, BAD_RA_FILENAME, NODE_TE_FILE)); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_disable_comment_te) { set_current_module_name("disable_comment"); FILE *f = fopen(DISABLE_COMMENT_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, DISABLE_COMMENT_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast); ck_assert_ptr_nonnull(ast); ck_assert_int_eq(NODE_TE_FILE, ast->flavor); ck_assert_ptr_nonnull(ast->next); ck_assert_int_eq(NODE_HEADER, ast->next->flavor); ck_assert_ptr_nonnull(ast->next->next); ck_assert_int_eq(NODE_DECL, ast->next->next->flavor); ck_assert_ptr_nonnull(ast->next->next->next); ck_assert_int_eq(NODE_AV_RULE, ast->next->next->next->flavor); ck_assert_str_eq("W-001", ast->next->next->next->exceptions); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_disable_comment_if) { set_current_module_name("disable_comment"); FILE *f = fopen(DISABLE_COMMENT_IF_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, DISABLE_COMMENT_IF_FILENAME, NODE_IF_FILE); ck_assert_ptr_nonnull(ast); ck_assert_ptr_nonnull(ast); ck_assert_int_eq(NODE_IF_FILE, ast->flavor); ck_assert_ptr_nonnull(ast->next); ck_assert_int_eq(NODE_INTERFACE_DEF, ast->next->flavor); ck_assert_str_eq("S-012", ast->next->exceptions); ck_assert_ptr_null(ast->next->next); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_bool_declarations) { set_current_module_name("bool_declarations"); FILE *f = fopen(BOOL_DECLARATION_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, BOOL_DECLARATION_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast); struct policy_node *current = ast; // top file node ck_assert_ptr_nonnull(current); ck_assert_int_eq(NODE_TE_FILE, current->flavor); ck_assert_ptr_nonnull(current->next); current = current->next; // header node ck_assert_ptr_null(current->parent); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_null(current->first_child); ck_assert_int_eq(NODE_HEADER, current->flavor); current = current->next; // first bool ck_assert_ptr_null(current->parent); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_null(current->first_child); ck_assert_int_eq(NODE_DECL, current->flavor); ck_assert_ptr_nonnull(current->data.d_data); ck_assert_int_eq(DECL_BOOL, current->data.d_data->flavor); ck_assert_str_eq("bool_one", current->data.d_data->name); ck_assert_ptr_null(current->data.d_data->attrs); current = current->next; // second bool ck_assert_ptr_null(current->parent); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_null(current->first_child); ck_assert_int_eq(NODE_DECL, current->flavor); ck_assert_ptr_nonnull(current->data.d_data); ck_assert_int_eq(DECL_BOOL, current->data.d_data->flavor); ck_assert_str_eq("bool_two", current->data.d_data->name); ck_assert_ptr_null(current->data.d_data->attrs); current = current->next; // third bool ck_assert_ptr_null(current->parent); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_null(current->first_child); ck_assert_int_eq(NODE_DECL, current->flavor); ck_assert_ptr_nonnull(current->data.d_data); ck_assert_int_eq(DECL_BOOL, current->data.d_data->flavor); ck_assert_str_eq("bool_three", current->data.d_data->name); ck_assert_ptr_null(current->data.d_data->attrs); current = current->next; // first tunable ck_assert_ptr_null(current->parent); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_null(current->first_child); ck_assert_int_eq(NODE_DECL, current->flavor); ck_assert_ptr_nonnull(current->data.d_data); ck_assert_int_eq(DECL_BOOL, current->data.d_data->flavor); ck_assert_str_eq("tunable_one", current->data.d_data->name); ck_assert_ptr_null(current->data.d_data->attrs); current = current->next; // second tunable ck_assert_ptr_null(current->parent); ck_assert_ptr_null(current->next); // last node ck_assert_ptr_nonnull(current->prev); ck_assert_ptr_null(current->first_child); ck_assert_int_eq(NODE_DECL, current->flavor); ck_assert_ptr_nonnull(current->data.d_data); ck_assert_int_eq(DECL_BOOL, current->data.d_data->flavor); ck_assert_str_eq("tunable_two", current->data.d_data->name); ck_assert_ptr_null(current->data.d_data->attrs); // check storage const char *mod_name; mod_name = look_up_in_decl_map("bool_one", DECL_BOOL); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq("bool_declarations", mod_name); mod_name = look_up_in_decl_map("bool_two", DECL_BOOL); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq("bool_declarations", mod_name); mod_name = look_up_in_decl_map("bool_three", DECL_BOOL); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq("bool_declarations", mod_name); mod_name = look_up_in_decl_map("tunable_one", DECL_BOOL); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq("bool_declarations", mod_name); mod_name = look_up_in_decl_map("tunable_two", DECL_BOOL); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq("bool_declarations", mod_name); // some cross checks ck_assert_ptr_null(look_up_in_decl_map("bool_four", DECL_BOOL)); ck_assert_ptr_null(look_up_in_decl_map("bool_one", DECL_TYPE)); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_file_flavor_mismatch) { set_current_module_name("basic"); FILE *f = fopen(BASIC_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f); ck_assert_ptr_null(yyparse_wrapper(f, BASIC_TE_FILENAME, NODE_IF_FILE)); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_extended_perms) { set_current_module_name("extended_perms"); FILE *f = fopen(EXTENDED_TE_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, EXTENDED_TE_FILENAME, NODE_TE_FILE); ck_assert_ptr_nonnull(ast); struct policy_node *current = ast; ck_assert_ptr_nonnull(current); ck_assert_int_eq(NODE_TE_FILE, current->flavor); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = ast->next; ck_assert_int_eq(NODE_HEADER, current->flavor); struct header_data *hd = current->data.h_data; ck_assert_int_eq(HEADER_MACRO, hd->flavor); ck_assert_str_eq("extended_perms", hd->module_name); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_DECL, current->flavor); struct declaration_data *dd = current->data.d_data; ck_assert_int_eq(DECL_TYPE, dd->flavor); ck_assert_str_eq("basic_t", dd->name); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_DECL, current->flavor); dd = current->data.d_data; ck_assert_int_eq(DECL_TYPE, dd->flavor); ck_assert_str_eq("basic_dev_t", dd->name); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_ALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("~", current->data.xav_data->perms->string); ck_assert_str_eq("0x8927", current->data.xav_data->perms->next->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_ALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("35072", current->data.xav_data->perms->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_ALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("0027", current->data.xav_data->perms->string); ck_assert_str_eq("0028", current->data.xav_data->perms->next->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_ALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("0", current->data.xav_data->perms->string); ck_assert_str_eq("0x00", current->data.xav_data->perms->next->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_ALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("0x0000", current->data.xav_data->perms->string); ck_assert_str_eq("-", current->data.xav_data->perms->next->string); ck_assert_str_eq("0x00ff", current->data.xav_data->perms->next->next->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_ALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("1024", current->data.xav_data->perms->string); ck_assert_str_eq("-", current->data.xav_data->perms->next->string); ck_assert_str_eq("2048", current->data.xav_data->perms->next->next->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_DONTAUDIT, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("1024-2048", current->data.xav_data->perms->string); ck_assert_str_eq("35072", current->data.xav_data->perms->next->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_AUDITALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("ioctl_macro", current->data.xav_data->perms->string); ck_assert_ptr_nonnull(current->next); ck_assert_ptr_null(current->first_child); current = current->next; ck_assert_int_eq(NODE_XAV_RULE, current->flavor); ck_assert_int_eq(AV_RULE_NEVERALLOW, current->data.xav_data->flavor); ck_assert_str_eq("ioctl", current->data.xav_data->operation); ck_assert_str_eq("ioctl_macro", current->data.xav_data->perms->string); ck_assert_str_eq("0x40ff-0x41ff", current->data.xav_data->perms->next->string); ck_assert_ptr_null(current->next); ck_assert_ptr_null(current->first_child); ck_assert_str_eq("extended_perms", look_up_in_decl_map("basic_t", DECL_TYPE)); ck_assert_int_eq(2, decl_map_count(DECL_TYPE)); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST START_TEST (test_parse_ifdef) { set_current_module_name("ifdef_block"); FILE *f = fopen(IFDEF_BLOCK_FILENAME, "r"); ck_assert_ptr_nonnull(f); struct policy_node *ast = yyparse_wrapper(f, IFDEF_BLOCK_FILENAME, NODE_TE_FILE); const struct policy_node *current = ast; const struct policy_node *ifelse_block; ck_assert_ptr_nonnull(current); ck_assert_int_eq(NODE_TE_FILE, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_HEADER, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_IFELSE, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_null(current->next); ifelse_block = current; current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_M4_ARG, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_nonnull(current->next); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_M4_SIMPLE_MACRO, current->flavor); ck_assert_str_eq("bool1", current->data.str); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_null(current->next); current = current->parent->next; ck_assert_int_eq(NODE_M4_ARG, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_nonnull(current->next); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_M4_SIMPLE_MACRO, current->flavor); ck_assert_str_eq("true", current->data.str); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_null(current->next); current = current->parent->next; ck_assert_int_eq(NODE_M4_ARG, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_nonnull(current->next); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_str_eq("source1", current->data.av_data->sources->string); ck_assert_str_eq("perm1", current->data.av_data->perms->string); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_str_eq("source1", current->data.av_data->sources->string); ck_assert_str_eq("perm2", current->data.av_data->perms->string); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_null(current->next); current = current->parent->next; ck_assert_int_eq(NODE_M4_ARG, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_nonnull(current->next); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_M4_SIMPLE_MACRO, current->flavor); ck_assert_str_eq("bool2", current->data.str); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_null(current->next); current = current->parent->next; ck_assert_int_eq(NODE_M4_ARG, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_nonnull(current->next); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_M4_SIMPLE_MACRO, current->flavor); ck_assert_str_eq("true", current->data.str); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_null(current->next); current = current->parent->next; ck_assert_int_eq(NODE_M4_ARG, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_nonnull(current->next); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_str_eq("source2", current->data.av_data->sources->string); ck_assert_str_eq("perm1", current->data.av_data->perms->string); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_str_eq("source2", current->data.av_data->sources->string); ck_assert_str_eq("perm2", current->data.av_data->perms->string); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_null(current->next); current = current->parent->next; ck_assert_int_eq(NODE_M4_ARG, current->flavor); ck_assert_ptr_nonnull(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent); ck_assert_ptr_null(current->next); current = current->first_child; ck_assert_int_eq(NODE_START_BLOCK, current->flavor); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_str_eq("source3", current->data.av_data->sources->string); ck_assert_str_eq("perm1", current->data.av_data->perms->string); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_nonnull(current->next); current = current->next; ck_assert_int_eq(NODE_AV_RULE, current->flavor); ck_assert_str_eq("source3", current->data.av_data->sources->string); ck_assert_str_eq("perm2", current->data.av_data->perms->string); ck_assert_ptr_null(current->first_child); ck_assert_ptr_eq(ifelse_block, current->parent->parent); ck_assert_ptr_null(current->next); current = current->parent; ck_assert_ptr_null(current->next); current = current->parent; ck_assert_ptr_eq(ifelse_block, current); ck_assert_ptr_null(current->next); free_policy_node(ast); cleanup_parsing(); fclose(f); } END_TEST static Suite *parsing_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Parsing"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_parse_basic_te); tcase_add_test(tc_core, test_parse_basic_if); tcase_add_test(tc_core, test_parse_uncommon_constructs); tcase_add_test(tc_core, test_parse_blocks); tcase_add_test(tc_core, test_parse_empty_file); tcase_add_test(tc_core, test_syntax_error); tcase_add_test(tc_core, test_parse_bad_role_allow); tcase_add_test(tc_core, test_disable_comment_te); tcase_add_test(tc_core, test_disable_comment_if); tcase_add_test(tc_core, test_bool_declarations); tcase_add_test(tc_core, test_file_flavor_mismatch); tcase_add_test(tc_core, test_extended_perms); tcase_add_test(tc_core, test_parse_ifdef); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = parsing_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_perm_macro.c0000644000175100001710000003377514167117255014546 00000000000000/* * Copyright 2020 The SELint Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "../src/startup.h" #include "../src/maps.h" #include "../src/selint_error.h" #include "../src/perm_macro.h" #include "../src/parse_functions.h" #define PERMS_PATH SAMPLE_POL_DIR "perms.spt" typedef uint32_t mask_t; extern void compute_perm_mask(const struct string_list *permissions, mask_t *mask_raw, mask_t *mask_extended); extern unsigned short popcount(mask_t x); START_TEST (test_permmacro_dirs) { enum selint_error res; struct string_list *permissions; char *check_str; mask_t mask_raw, mask_extended; // parse permission macros res = load_obj_perm_sets_source(PERMS_PATH); ck_assert_int_eq(SELINT_SUCCESS, res); ck_assert_ptr_null(permmacro_check("dir", NULL)); // check 0 permissions = sl_from_str("getattr"); ck_assert_ptr_nonnull(permissions); ck_assert_ptr_null(permmacro_check("dir", permissions)); free_string_list(permissions); // check 1 permissions = sl_from_str("search_dir_perms"); ck_assert_ptr_nonnull(permissions); ck_assert_ptr_null(permmacro_check("dir", permissions)); free_string_list(permissions); // check 2 permissions = sl_from_strs(2, "getattr", "search"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(2, popcount(mask_raw)); ck_assert_int_eq(2, popcount(mask_extended)); ck_assert_ptr_null(permmacro_check("dir", permissions)); free_string_list(permissions); //check 3 permissions = sl_from_strs(3, "getattr", "search", "open"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(3, popcount(mask_raw)); ck_assert_int_eq(3, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: search_dir_perms (replacing { getattr search open }, would add (none))", check_str); free(check_str); free_string_list(permissions); // check 4 permissions = sl_from_strs(2, "search", "open"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(2, popcount(mask_raw)); ck_assert_int_eq(3, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: search_dir_perms (replacing { search open }, would add { getattr })", check_str); free(check_str); free_string_list(permissions); // check 5 permissions = sl_from_strs(2, "create", "mounton"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(2, popcount(mask_raw)); ck_assert_int_eq(4, popcount(mask_extended)); ck_assert_ptr_null(permmacro_check("dir", permissions)); free_string_list(permissions); // check 6 permissions = sl_from_strs(5, "open", "read", "write", "remove_name", "add_name"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(5, popcount(mask_raw)); ck_assert_int_eq(10, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: rw_dir_perms (replacing { open read write remove_name add_name }, would add { ioctl getattr lock search })", check_str); free(check_str); free_string_list(permissions); // check 6 permissions = sl_from_strs(2, "search_dir_perms", "read"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(4, popcount(mask_raw)); ck_assert_int_eq(6, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: read_dir_perms (replacing { search_dir_perms read }, would add { ioctl lock })", check_str); free(check_str); free_string_list(permissions); // check 7 permissions = sl_from_strs(3, "search_dir_perms", "read", "quotaon"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(5, popcount(mask_raw)); ck_assert_int_eq(7, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: read_dir_perms (replacing { search_dir_perms read }, would add { ioctl lock })", check_str); free(check_str); free_string_list(permissions); // check 7 permissions = sl_from_strs(3, "search_dir_perms", "read", "some_new_perm"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(5, popcount(mask_raw)); ck_assert_int_eq(7, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: read_dir_perms (replacing { search_dir_perms read }, would add { ioctl lock })", check_str); free(check_str); free_string_list(permissions); // check 8 permissions = sl_from_strs(4, "relabel_dir_perms", "open", "read", "search"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(6, popcount(mask_raw)); ck_assert_int_eq(8, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: read_dir_perms (replacing { open read search }, would add { ioctl lock })", check_str); free(check_str); free_string_list(permissions); // check 9 permissions = sl_from_strs(6, "create", "open", "read", "add_name", "remove_name", "rmdir"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(6, popcount(mask_raw)); ck_assert_int_eq(14, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: control_dir_perms (replacing { create open read add_name remove_name rmdir }, would add { ioctl write getattr setattr lock unlink link rename reparent search })", check_str); free(check_str); free_string_list(permissions); // check 10 permissions = sl_from_strs(3, "search", "open", "some_new_perm"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(3, popcount(mask_raw)); ck_assert_int_eq(4, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: search_dir_perms (replacing { search open }, would add { getattr })", check_str); free(check_str); free_string_list(permissions); // check 11 permissions = sl_from_strs(3, "search", "open", "audit_access"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(3, popcount(mask_raw)); ck_assert_int_eq(4, popcount(mask_extended)); check_str = permmacro_check("dir", permissions); ck_assert_str_eq("Suggesting permission macro: search_dir_perms (replacing { search open }, would add { getattr })", check_str); free(check_str); free_string_list(permissions); // cleanup cleanup_parsing(); } END_TEST START_TEST (test_permmacro_files) { enum selint_error res; struct string_list *permissions; char *check_str; mask_t mask_raw, mask_extended; // parse permission macros res = load_obj_perm_sets_source(PERMS_PATH); ck_assert_int_eq(SELINT_SUCCESS, res); // check 1 ck_assert_ptr_null(permmacro_check("file", NULL)); // check 2 permissions = sl_from_str("getattr"); ck_assert_ptr_nonnull(permissions); ck_assert_ptr_null(permmacro_check("file", permissions)); free_string_list(permissions); // check 3 permissions = sl_from_strs(3, "open", "read", "lock"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(3, popcount(mask_raw)); ck_assert_int_eq(6, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: read_file_perms (replacing { open read lock }, would add { ioctl getattr })", check_str); free(check_str); free_string_list(permissions); // check 4 permissions = sl_from_str("read_no_lock_file_perms"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(4, popcount(mask_raw)); ck_assert_int_eq(6, popcount(mask_extended)); check_str = permmacro_check("file", permissions); // do not suggest read_file_perms ck_assert_ptr_null(check_str); free(check_str); free_string_list(permissions); // check 5 permissions = sl_from_strs(2, "map", "read_file_perms"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(6, popcount(mask_raw)); ck_assert_int_eq(7, popcount(mask_extended)); check_str = permmacro_check("file", permissions); // do not 'suggesting mmap_read_file_perms replacing { map } (would add (none))' ck_assert_ptr_null(check_str); free_string_list(permissions); // check 6 permissions = sl_from_strs(2, "relabelfrom", "relabelto"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(2, popcount(mask_raw)); ck_assert_int_eq(3, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: relabel_file_perms (replacing { relabelfrom relabelto }, would add { getattr })", check_str); free(check_str); free_string_list(permissions); // check 7 permissions = sl_from_strs(5, "open", "read", "write", "create", "unlink"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(5, popcount(mask_raw)); ck_assert_int_eq(12, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: control_file_perms (replacing { open read write create unlink }, would add { ioctl getattr setattr lock append link rename })", check_str); free(check_str); free_string_list(permissions); // check 8 permissions = sl_from_strs(2, "getattr", "rename"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(2, popcount(mask_raw)); ck_assert_int_eq(2, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: rename_file_perms (replacing { getattr rename }, would add (none))", check_str); free(check_str); free_string_list(permissions); // check 9 permissions = sl_from_strs(2, "read_file_perms", "write_file_perms"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(6, popcount(mask_raw)); ck_assert_int_eq(8, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: rw_file_perms (replacing { read_file_perms write_file_perms }, would add (none))", check_str); free(check_str); free_string_list(permissions); // check 10 permissions = sl_from_strs(3, "read", "write", "open"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(3, popcount(mask_raw)); ck_assert_int_eq(8, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: rw_file_perms (replacing { read write open }, would add { ioctl getattr lock })", check_str); free(check_str); free_string_list(permissions); // check 11 permissions = sl_from_strs(2, "read", "write"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(2, popcount(mask_raw)); ck_assert_int_eq(7, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: rw_no_open_file_perms (replacing { read write }, would add { ioctl getattr lock })", check_str); free(check_str); free_string_list(permissions); // check 12 permissions = sl_from_strs(3, "read_file_perms", "relabelfrom", "relabelto"); ck_assert_ptr_nonnull(permissions); mask_raw = mask_extended = 0; compute_perm_mask(permissions, &mask_raw, &mask_extended); ck_assert_int_eq(7, popcount(mask_raw)); ck_assert_int_eq(8, popcount(mask_extended)); check_str = permmacro_check("file", permissions); ck_assert_str_eq("Suggesting permission macro: relabel_file_perms (replacing { relabelfrom relabelto }, would add (none))", check_str); free(check_str); free_string_list(permissions); // cleanup cleanup_parsing(); } END_TEST static Suite *startup_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Permmacro"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_permmacro_dirs); tcase_add_test(tc_core, test_permmacro_files); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = startup_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/functional/0000755000175100001710000000000014167117420013316 500000000000000selint-1.2.1/tests/functional/end-to-end.bats0000644000175100001710000003055714167117255016063 00000000000000#!/usr/bin/env/bats # Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. SELINT_PATH=../../src/selint do_test() { local CHECK_ID=$1 local FILENAME=$2 local EXPECT=$3 local ARGS=$4 run ${SELINT_PATH} -s -c tmp.conf ${ARGS} ./policies/check_triggers/${FILENAME} ./policies/check_triggers/modules.conf ./policies/check_triggers/obj_perm_sets.spt ./policies/check_triggers/access_vectors echo $output [ "$status" -eq 0 ] count=$(echo ${output} | grep -o ${CHECK_ID} | wc -l) echo "Status: $status, Count: $count (expected ${EXPECT})" [ "$count" -eq ${EXPECT} ] } test_one_check_expect() { local CHECK_ID=$1 local FILENAME=$2 local EXPECT=$3 echo "disable = { $CHECK_ID } " > tmp.conf # E-010 echo "custom_te_simple_macros = { ignored_bare_word }" >> tmp.conf do_test ${CHECK_ID} ${FILENAME} 0 echo "enable_source = { $CHECK_ID }" >> tmp.conf do_test ${CHECK_ID} ${FILENAME} ${EXPECT} do_test ${CHECK_ID} ${FILENAME} 0 "-d $CHECK_ID" do_test ${CHECK_ID} ${FILENAME} ${EXPECT} "-e $CHECK_ID" do_test ${CHECK_ID} ${FILENAME} ${EXPECT} "-e $CHECK_ID -d $CHECK_ID" rm tmp.conf } test_ordering() { local CHECK_DIR="./policies/check_triggers/C-001/" local FILENAME_PREFIX=$1 for ORDER_CONF in "ref" "lax" do echo "Checking ${FILENAME_PREFIX} in order ${ORDER_CONF}" run ${SELINT_PATH} -rs -c configs/order_${ORDER_CONF}.conf -e C-001 -E --context=${CHECK_DIR}interfaces ${CHECK_DIR}${FILENAME_PREFIX}.te ./policies/check_triggers/modules.conf echo ${output} while read p; do echo "Checking for $p" count=$(echo ${output} | grep -o ${p} | wc -l) [ "$count" -eq "1" ] done < "${CHECK_DIR}/${FILENAME_PREFIX}.expect.${ORDER_CONF}" local EXPECT_COUNT=$(cat ${CHECK_DIR}/${FILENAME_PREFIX}.expect.${ORDER_CONF} | wc -l) count=$(echo ${output} | grep -o C-001 | wc -l) echo "Expecting: ${EXPECT_COUNT}, got: $count" [ "$count" -eq "${EXPECT_COUNT}" ] done } test_one_check() { test_one_check_expect $1 $2 1 } test_parse_error_run() { local USE_VALGRIND=$1 test_parse_error_impl $USE_VALGRIND test1.te test1.output test_parse_error_impl $USE_VALGRIND test2.te test2.output printf "#comment\n policy_module( test2, \n \n\n 0.0.1 \n ) \n\n" > ./policies/parse_errors/test3_tmp.if test_parse_error_impl $USE_VALGRIND test3_tmp.if test3.output test_parse_error_impl $USE_VALGRIND test4.te test4.output printf "policy_module(test5, 0.0.1)\r\n\r\n# comment\r\nallow \r\n source\r\ntarget \r\n clas\r\n perm\r\n; # comment\r\n\r\n" > ./policies/parse_errors/test5_tmp.te test_parse_error_impl $USE_VALGRIND test5_tmp.te test5.output printf "#comment\r\n policy_module( test2, \r\n \r\n\r\n 0.0.1 \r\n ) \r\n\r\n" > ./policies/parse_errors/test6_tmp.if test_parse_error_impl $USE_VALGRIND test6_tmp.if test6.output test_parse_error_impl $USE_VALGRIND test7.if test7.output test_parse_error_impl $USE_VALGRIND test8.te test8.output test_parse_error_impl $USE_VALGRIND test9.te test9.output } test_parse_error_impl() { local USE_VALGRIND=$1 local SOURCE_FILENAME=$2 local OUTPUT_FILENAME=$3 if [ $USE_VALGRIND -eq 1 ]; then run valgrind --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=23 ${SELINT_PATH} -c configs/default.conf ./policies/parse_errors/${SOURCE_FILENAME} [ "$status" -eq 70 ] else run ${SELINT_PATH} -c configs/default.conf ./policies/parse_errors/${SOURCE_FILENAME} echo ${output} [ "$status" -eq 70 ] local EXPECTED_OUTPUT=$(cat ./policies/parse_errors/${OUTPUT_FILENAME}) echo ${EXPECTED_OUTPUT} # compatibility for different bison versions and ignore NOTE output local NORMALIZED_OUTPUT=$(grep -vE '^Note: ' <<< "${output/ \$end/ end of file}") echo ${NORMALIZED_OUTPUT} [ "${NORMALIZED_OUTPUT}" == "${EXPECTED_OUTPUT}" ] fi } @test "C-001" { test_ordering "simple" test_ordering "interleaved" test_ordering "optional" test_ordering "role_ifs" test_ordering "types_in_requires" test_ordering "kernel_module_first" test_ordering "if_in_optional" } @test "C-004" { test_one_check "C-004" "c04.if" } @test "C-005" { test_one_check_expect "C-005" "c05.te" 2 test_one_check "C-005" "c05.if" } @test "C-006" { test_one_check_expect "C-006" "c06.pass.if" 0 test_one_check_expect "C-006" "c06.warn.if" 5 } @test "C-007" { test_one_check "C-007" "c07.te" test_one_check "C-007" "c07.if" } @test "S-001" { test_one_check "S-001" "s01.te" } @test "S-002" { test_one_check "S-002" "s02*" } @test "S-003" { test_one_check "S-003" "s03.te" } @test "S-004" { test_one_check "S-004" "s04.*" } @test "S-005" { test_one_check "S-005" "s05.if" } @test "S-006" { test_one_check "S-006" "s06.te" } @test "S-007" { test_one_check "S-007" "s07.fc" } @test "S-008" { test_one_check "S-008" "s08.if" } @test "S-009" { test_one_check_expect "S-009" "s09.pass.te" 0 test_one_check_expect "S-009" "s09.warn.te" 6 } @test "W-001" { test_one_check_expect "W-001" "w01*" 5 } @test "W-002" { test_one_check_expect "W-002" "w02.*" 2 test_one_check "W-002" "w02_role.*" } @test "W-003" { test_one_check "W-003" "w03.if" test_one_check "W-003" "w03_role.if" test_one_check_expect "W-003" "w03_ta.if" 0 test_one_check_expect "W-003" "w03_alias.if" 0 test_one_check_expect "W-003" "w03_stub.if" 0 } @test "W-004" { test_one_check "W-004" "w04.fc" } @test "W-005" { test_one_check "W-005" "w05*" } @test "W-006" { test_one_check "W-006" "w06.if" } @test "W-007" { test_one_check "W-007" "w07.if" test_one_check_expect "W-007" "w07.0.te" 0 test_one_check "W-007" "w07.1.te" } @test "W-008" { test_one_check "W-008" "w08.1.te" test_one_check "W-008" "w08.2.te" } @test "W-009" { test_one_check "W-009" "w09.te" } @test "W-010" { test_one_check "W-010" "w10.warn.te" test_one_check_expect "W-010" "w10.pass.te" 0 } @test "W-011" { test_one_check "W-011" "w11.*" } @test "E-002" { test_one_check "E-002" "e02.fc" } @test "E-003" { test_one_check "E-003" "e03e04e05.fc" } @test "E-004" { test_one_check "E-004" "e03e04e05.fc" } @test "E-005" { test_one_check "E-005" "e03e04e05.fc" } @test "E-006" { test_one_check "E-006" "e06.*" } @test "E-007" { test_one_check_expect "E-007" "e07.warn.te" 5 test_one_check_expect "E-007" "e07.pass.te" 0 } @test "E-008" { test_one_check_expect "E-008" "e08.warn.te" 4 test_one_check_expect "E-008" "e08.pass.te" 0 } @test "E-009" { test_one_check_expect "E-009" "e09.te" 4 } @test "E-010" { test_one_check_expect "E-010" "e10.warn.te" 9 test_one_check_expect "E-010" "e10.pass.te" 0 } @test "assume_user" { touch tmp.conf do_test "E-003" "e03e04e05.fc" 1 "-e E-003" echo "assume_users = { system_u }" >> tmp.conf do_test "E-003" "e03e04e05.fc" 0 "-e E-003" rm tmp.conf } @test "assume_role" { touch tmp.conf do_test "E-004" "e03e04e05.fc" 1 "-e E-004" echo "assume_roles = { object_r }" >> tmp.conf do_test "E-004" "e03e04e05.fc" 0 "-e E-004" rm tmp.conf } @test "usage" { run ${SELINT_PATH} -c configs/empty.conf [ "$status" -eq 64 ] usage_presence=$(echo ${output} | grep -o "^Usage" | wc -l) [ "$usage_presence" -eq 1 ] run ${SELINT_PATH} -c configs/empty.conf -Z [ "$status" -eq 64 ] usage_presence=$(echo ${output} | grep -o "Usage" | wc -l) [ "$usage_presence" -eq 1 ] message_presence=$(echo ${output} | grep -o "invalid option -- 'Z'" | wc -l) [ "$message_presence" -eq 1 ] } @test "Enable/disable" { run ${SELINT_PATH} -c configs/empty.conf -e W-002 -e W-003 -d S-002 -d C-002 -r -s policies/check_triggers [ "$status" -eq 0 ] count=$(echo ${output} | grep -o "S-002" | wc -l) [ "$count" -eq 0 ] count=$(echo ${output} | grep -o "C-002" | wc -l) [ "$count" -eq 0 ] count=$(echo ${output} | grep -o "W-002" | wc -l) [ "$count" -gt 0 ] count=$(echo ${output} | grep -o "W-003" | wc -l) [ "$count" -gt 0 ] } @test "verbose mode" { run ${SELINT_PATH} -c configs/default.conf -r -s -v policies/check_triggers [ "$status" -eq 0 ] verbose_presence=$(echo ${output} | grep -o "^Verbose" | wc -l) [ "$verbose_presence" -eq 1 ] } @test "valgrind" { run valgrind --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 ${SELINT_PATH} -c configs/default.conf -r -s policies/check_triggers [ "$status" -eq 0 ] } @test "nesting_gen_req" { run ${SELINT_PATH} -c configs/default.conf -e W-002 -E -s policies/misc/nesting.* [ "$status" -eq 0 ] count=$(echo ${output} | grep -o "W-002" | wc -l) echo "Status: $status, Count: $count (expected 1)" echo $output [ "$count" -eq 1 ] count=$(echo ${output} | grep -o "foo_data_t" | wc -l) echo "Status: $status, Count: $count (expected 1)" echo $output [ "$count" -eq 1 ] count=$(echo ${output} | grep -o "foo_log_t" | wc -l) echo "Status: $status, Count: $count (expected 0)" echo $output [ "$count" -eq 0 ] } @test "disable comment" { run ${SELINT_PATH} -c configs/default.conf -F -e W-002 -E -s policies/misc/disable.* [ "$status" -eq 0 ] count=$(echo ${output} | grep -o "W-002" | wc -l) echo "Status: $status, Count: $count (expected 0)" echo $output [ "$count" -eq 0 ] echo "Part I" run ${SELINT_PATH} -F -s -c configs/default.conf policies/misc/disable_multiple* [ "$status" -eq 0 ] echo "Part II" run ${SELINT_PATH} -F -s -c configs/default.conf -d S-008 policies/misc/disable_require_start.* [ "$status" -eq 0 ] echo "Part III" run ${SELINT_PATH} -F -s -c configs/default.conf policies/misc/disable_require_decl.* [ "$status" -eq 0 ] } @test "nonexistent file" { run ${SELINT_PATH} -s -c configs/default.conf doesnt_exist.te [ "$status" -eq 70 ] run ${SELINT_PATH} -s -c configs/default.conf doesnt_exist.if [ "$status" -eq 70 ] run ${SELINT_PATH} -s -c configs/default.conf doesnt_exist.fc [ "$status" -eq 70 ] } @test "Broken config" { run valgrind --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 ${SELINT_PATH} -c configs/broken.conf -rs policies/check_triggers [ "$status" -eq 78 ] } @test "Bad check ids" { run ${SELINT_PATH} -s -c configs/default.conf policies/misc/no_issues.te count=$(echo ${output} | grep -o "Warning: Failed to locate modules.conf file." | wc -l) [ "$count" -eq 1 ] #"Failed to find a valid modules.conf" run ${SELINT_PATH} -s -c configs/default.conf -e foo policies/misc/no_issues.te count=$(echo ${output} | grep -o "not a valid check id" | wc -l) [ "$count" -eq 1 ] run ${SELINT_PATH} -s -c configs/default.conf -d foo policies/misc/no_issues.te count=$(echo ${output} | grep -o "not a valid check id" | wc -l) [ "$count" -eq 1 ] run ${SELINT_PATH} -s -c configs/bad_ids.conf policies/misc/no_issues.te count=$(echo ${output} | grep -o "not a valid check id" | wc -l) [ "$count" -eq 2 ] run ${SELINT_PATH} -s -c configs/bad_ids.conf -e foo -d bar -d baz policies/misc/no_issues.te count=$(echo ${output} | grep -o "not a valid check id" | wc -l) [ "$count" -eq 5 ] } @test "context flag" { touch tmp.conf do_test "W-001" "../misc/needs_context.te" 0 do_test "W-001" "../misc/needs_context.te" 1 "--context=policies/context" do_test "W-001" "../misc/needs_context.te" 1 "--context=policies/context2" do_test "W-001" "../misc/needs_context.te" 2 "--context=policies/context --context=policies/context2" rm tmp.conf } @test "run_summary" { run ${SELINT_PATH} -c configs/default.conf -rsS policies/check_triggers count=$(echo ${output} | grep -o "Found the following issue counts" | wc -l) [ "$count" -eq 1 ] for SEV in "C" "S" "W" "E" do count=$(echo ${output} | grep -E -o "${SEV}-00[0-9]: [0-9]+" | wc -l) [ "$count" -ge 1 ] done } @test "custom_fc_macros" { run ${SELINT_PATH} -c configs/default.conf -s policies/misc/fc_macros.fc count=$(echo ${output} | grep -o "E-002" | wc -l) [ "$count" -eq 1 ] run ${SELINT_PATH} -c configs/fc_macros.conf -s policies/misc/fc_macros.fc count=$(echo ${output} | grep -o "E-002" | wc -l) echo ${output} [ "$count" -eq 0 ] } @test "parse_error_printing" { test_parse_error_run 0 } @test "parse_error_printing_valgrind" { if [ -z ${BATS_TIME_EXPENSIVE} ]; then skip "BATS_TIME_EXPENSIVE not set" fi test_parse_error_run 1 } selint-1.2.1/tests/functional/policies/0000755000175100001710000000000014167117420015125 500000000000000selint-1.2.1/tests/functional/policies/context2/0000755000175100001710000000000014167117420016673 500000000000000selint-1.2.1/tests/functional/policies/context2/context2.te0000644000175100001710000000012614167117255020720 00000000000000policy_module(context2, 1.0) type context2_t; # This type should exist in the policy selint-1.2.1/tests/functional/policies/context2/context2.if0000644000175100001710000000035414167117255020711 00000000000000## Interfaces to test the --context selint flag ## Execute racoon and allow the specified role the domain. ## ## ## ## Domain allowed to transition. ## ## ## ## ## Role allowed access. ## ## ## # # interface(`ipsec_run_racoon',` gen_require(` type racoon_t; ') ipsec_domtrans_racoon($1) role $2 types racoon_t; ') # Comment interface(`this_one_fails',` gen_require(` type foo_t, bar_t; ') allow $1 foo_t:file read; ') selint-1.2.1/tests/functional/policies/check_triggers/s07.fc0000644000175100001710000000007214167117255020760 00000000000000/usr/bin/foo -- gen_context(system_u:object_r:foo_exec_t) selint-1.2.1/tests/functional/policies/check_triggers/w03_role.if0000644000175100001710000000120614167117255022007 00000000000000######################################## ## ## Execute racoon and allow the specified role the domain. ## ## ## ## Domain allowed to transition. ## ## ## ## ## Role allowed access. ## ## ## # # interface(`ipsec_run_racoon',` gen_require(` type racoon_t; ') ipsec_domtrans_racoon($1) role $2 types racoon_t; ') # Comment interface(`this_one_fails',` gen_require(` type foo_t; role foo_r; ') allow $1 foo_t:file read; ') selint-1.2.1/tests/functional/policies/check_triggers/w04.fc0000644000175100001710000000011614167117255020760 00000000000000/usr/bin/file_with_dot.txt -- gen_context(system_u:object_r:user_home_t, s0) selint-1.2.1/tests/functional/policies/check_triggers/e02.fc0000644000175100001710000000010014167117255020725 00000000000000/usr/bin/foo -- gen_deadbeef(system_u:object_r:foo_exec_t, s0) selint-1.2.1/tests/functional/policies/check_triggers/e06.if0000644000175100001710000000003114167117255020742 00000000000000interface(`clashes',` ') selint-1.2.1/tests/functional/policies/check_triggers/e10.warn.te0000644000175100001710000000057114167117255021726 00000000000000policy_module(e10_warn, 1.0) bare_word bare word ifdef(`foo',` # comment bare_word ') ifelse(`bar', `true', ` bare_word ',`$2', `true', ` bare_word ') ifelse(`bar', `true', ` bare_word ',`$2', `true', ` bare_word', ` bare_word ') # NOTE: a bare word inside define() body currently doesn't get flagged define(`not_really_a_bare_word',` bare_word ') selint-1.2.1/tests/functional/policies/check_triggers/s05.if0000644000175100001710000000004114167117255020760 00000000000000interface(`bar',` type $1_t; ') selint-1.2.1/tests/functional/policies/check_triggers/w07.1.te0000644000175100001710000000007614167117255021147 00000000000000policy_module(w07, 1.0) attribute a1; type t1; foo(a1 - t1) selint-1.2.1/tests/functional/policies/check_triggers/c05.te0000644000175100001710000000014414167117255020756 00000000000000policy_module(c05, 1.0) allow source target:cls { foo bar }; allow source target:cls { foo foo }; selint-1.2.1/tests/functional/policies/check_triggers/e06.te0000644000175100001710000000005414167117255020761 00000000000000policy_module(e06, 1.0) attribute clashes; selint-1.2.1/tests/functional/policies/check_triggers/w09.te0000644000175100001710000000005414167117255021006 00000000000000policy_module(different_name, 1.0) type a; selint-1.2.1/tests/functional/policies/check_triggers/access_vectors0000644000175100001710000000007114167117255022765 00000000000000class file { read open } class dir { read open search } selint-1.2.1/tests/functional/policies/check_triggers/C-001/0000755000175100001710000000000014167117420020570 500000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/kernel_module_first.expect.lax0000644000175100001710000000000014167117255026535 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/types_in_requires.expect.lax0000644000175100001710000000000014167117255026252 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/simple.te0000644000175100001710000000030014167117255022332 00000000000000policy_module(simple, 1.0) type foo_t; type foo_data_t; manage_files_pattern(foo_t, foo_data_t, foo_data_t) kernel_read_system_state(foo_t) logging_search_logs(foo_t) domain_type(foo_t) selint-1.2.1/tests/functional/policies/check_triggers/C-001/optional.te0000644000175100001710000000043614167117255022700 00000000000000policy_module(optional, 1.0) type foo_t; domain_type(foo_t) allow foo_t self:capability dac_override; kernel_read_system_state(foo_t) optional_policy(` foo_do_stuff(foo_t) ') tunable_policy(`foo_read_audit',` logging_read_audit_log(foo_t) logging_set_audit_parameters(foo_t) ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/0000755000175100001710000000000014167117420022713 500000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/system/0000755000175100001710000000000014167117420024237 500000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/system/logging.if0000644000175100001710000000065014167117255026134 00000000000000# Fake interfaces for testing C-001 # Comment interface(`logging_send_audit_msgs',` gen_require(` type audit_msgs_t; ') fake_send_pattern($1, audit_msgs_t) ') # Comment interface(`logging_read_audit_log',` gen_require(` type audit_log_t; ') read_files_pattern($1, audit_log_t, audit_log_t) ') #Comment interface(`logging_search_logs',` gen_require(` type log_t; ') search_dirs_pattern($1, log_t, log_t) ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/system/init.if0000644000175100001710000000034414167117255025451 00000000000000# Fake init interfaces # Fake init_system_domain interface(`init_system_domain',` gen_require(` type init_script_t; attribute someattribute; ') typeattribute $1 someattribute; domtrans_pattern(init_script_t, $1, $2) ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/kernel/0000755000175100001710000000000014167117420024173 500000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/kernel/kernel.if0000644000175100001710000000026514167117255025724 00000000000000# Fake interfaces for testing ordering # Comment interface(`kernel_read_system_state',` gen_require(` type system_state_t; ') allow $1 system_state_t:file read_file_perms; ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/kernel/domain.if0000644000175100001710000000114714167117255025713 00000000000000# This file contains stubbed interfaces for domains for use in test #Stubbed domain_type interface(`domain_type',` domain_other_interface_type($1) ') # Other interface is called to check transform interface calculations interface(`domain_other_interface_type',` gen_require(` attribute domain; ') typeattribute $1 domain; ') # Comment interface(`domain_first_access',` gen_require(` type domain_foo_t; ') read_files_pattern($1, domain_foo_t, domain_foo_t) ') # Comment interface(`domain_second_access',` gen_require(` type domain_bar_t; ') read_files_pattern($1, domain_bar_t, domain_bar_t) ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/other/0000755000175100001710000000000014167117420024034 500000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/other/mta.if0000644000175100001710000000100014167117255025052 00000000000000# Fake interfaces for test # Do the things interface(`foo_do_stuff',` gen_require(` type stuff_t; ') do_things_pattern($1, stuff_t, stuff_t) ') # Need a second interface interface(`foo_do_other_stuff',` gen_require(` type other_stuff_t; ') do_things_pattern($1, other_stuff_t, other_stuff_t) ') # Transform interface interface(`foo_writer_domain',` gen_require(` attribute foo_writer; type foo_target_t; ') typeattribute $1 foo_writer; write_files_pattern($1, foo_target_t, foo_target_t) ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/interfaces/other/role_ifs.if0000644000175100001710000000015014167117255026100 00000000000000interface(`role_ifs_associate_role',` gen_require(` role some_role; ') role some_role types $1; ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/role_ifs.expect.ref0000644000175100001710000000000314167117255024276 0000000000000011 selint-1.2.1/tests/functional/policies/check_triggers/C-001/kernel_module_first.te0000644000175100001710000000036214167117255025105 00000000000000policy_module(kernel_module_first, 1.0) type foo_t; domain_type(foo_t) allow foo_t self:capability { sys_admin net_admin lease }; domain_first_access(foo_t) domain_second_access(foo_t) kernel_read_system_state(foo_t) foo_do_stuff(foo_t) selint-1.2.1/tests/functional/policies/check_triggers/C-001/decl_in_block.expect.ref0000644000175100001710000000000014167117255025240 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/if_in_optional.te0000644000175100001710000000037414167117255024045 00000000000000policy_module(ifdef_in_optional, 1.0) type foo_t; domain_type(foo_t) allow foo_t self:tcp_socket { create_socket_perms rw_socket_perms }; optional_policy(` foo_do_stuff(foo_t) ') optional_policy(` ifdef(`bar',` foo_do_other_stuff(foo_t) ') ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/types_in_requires.te0000644000175100001710000000024614167117255024623 00000000000000policy_module(types_in_requires, 1.0) type foo_t; allow foo_t self:process setuid; require { type bar_log_t; } append_files_pattern(foo_t, bar_log_t, bar_log_t) selint-1.2.1/tests/functional/policies/check_triggers/C-001/if_in_optional.expect.lax0000644000175100001710000000000014167117255025472 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/interleaved.expect.lax0000644000175100001710000000000314167117255025006 0000000000000015 selint-1.2.1/tests/functional/policies/check_triggers/C-001/kernel_module_first.expect.ref0000644000175100001710000000000314167117255026530 0000000000000011 selint-1.2.1/tests/functional/policies/check_triggers/C-001/types_in_requires.expect.ref0000644000175100001710000000000014167117255026242 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/simple.expect.ref0000644000175100001710000000000314167117255023765 0000000000000013 selint-1.2.1/tests/functional/policies/check_triggers/C-001/decl_in_block.expect.lax0000644000175100001710000000000014167117255025250 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/decl_in_block.te0000644000175100001710000000050714167117255023621 00000000000000policy_module(decl_in_block, 1.0) type foo_t; domain_type(foo_t) type foo_exec_t; allow foo_t self:capability mac_admin; ifdef(`init_systemd',` init_system_domain(foo_t, foo_exec_t) ') tunable_policy(`some_tunable',` # C-001 doesn't care if it's redundant domain_type(foo_t) ') optional_policy(` foo_writer(foo_t) ') selint-1.2.1/tests/functional/policies/check_triggers/C-001/simple.expect.lax0000644000175100001710000000000314167117255023775 0000000000000013 selint-1.2.1/tests/functional/policies/check_triggers/C-001/interleaved.te0000644000175100001710000000062014167117255023350 00000000000000policy_module(interleaved, 1.0) type domA_t; domain_type(domA_t) type domB_t; domain_type(domB_t) type resource_t; files_type(resource_t) manage_files_pattern(domA_t, resource_t, resource_t) logging_send_audit_msgs(domA_t) logging_send_audit_msgs(domB_t) kernel_read_system_state(domA_t) optional_policy(` apache_manage_config(domA_t) ') manage_files_pattern(domB_t, resource_t, resource_t) selint-1.2.1/tests/functional/policies/check_triggers/C-001/role_ifs.expect.lax0000644000175100001710000000000314167117255024306 0000000000000011 selint-1.2.1/tests/functional/policies/check_triggers/C-001/optional.expect.lax0000644000175100001710000000000014167117255024326 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/interleaved.expect.ref0000644000175100001710000000000614167117255025001 0000000000000014 15 selint-1.2.1/tests/functional/policies/check_triggers/C-001/optional.expect.ref0000644000175100001710000000000314167117255024321 0000000000000011 selint-1.2.1/tests/functional/policies/check_triggers/C-001/if_in_optional.expect.ref0000644000175100001710000000000014167117255025462 00000000000000selint-1.2.1/tests/functional/policies/check_triggers/C-001/role_ifs.te0000644000175100001710000000030314167117255022646 00000000000000policy_module(role_ifs, 1.0) type foo_t; role_ifs_associate_role(foo_t) type bar_t; allow foo_t self:capability mac_override; allow foo_t bar_t:process signal; role_ifs_associate_role(bar_t) selint-1.2.1/tests/functional/policies/check_triggers/w01_other.te0000644000175100001710000000013514167117255022177 00000000000000policy_module(w01_other, 1.0) type foo_t; attribute foo_domain; attribute_role foo_roles; selint-1.2.1/tests/functional/policies/check_triggers/w05.te0000644000175100001710000000006614167117255021005 00000000000000policy_module(w05, 1.0) type bar_t; foo_read(bar_t) selint-1.2.1/tests/functional/policies/check_triggers/s04.if0000644000175100001710000000006114167117255020761 00000000000000template(`foo',` ') interface(`bar',` foo() ') selint-1.2.1/tests/functional/policies/context/0000755000175100001710000000000014167117420016611 500000000000000selint-1.2.1/tests/functional/policies/context/context.if0000644000175100001710000000035114167117255020542 00000000000000## Interfaces to test the --context selint flag #include #include "test_utils.h" #include "../src/if_checks.h" #include "../src/check_hooks.h" #include "../src/maps.h" START_TEST (test_check_interface_defs_have_comment) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); head->flavor = NODE_COMMENT; head->next = calloc(1, sizeof(struct policy_node)); head->next->prev = head; head->next->flavor = NODE_INTERFACE_DEF; struct check_result *res = check_interface_definitions_have_comment(NULL, head->next); ck_assert_ptr_null(res); head->next->flavor = NODE_TEMP_DEF; res = check_interface_definitions_have_comment(NULL, head->next); ck_assert_ptr_null(res); head->flavor = NODE_IF_FILE; res = check_interface_definitions_have_comment(NULL, head->next); ck_assert_ptr_nonnull(res); ck_assert_int_eq('C', res->severity); ck_assert_int_eq(C_ID_IF_COMMENT, res->check_id); free_check_result(res); head->next->flavor = NODE_AV_RULE; res = check_interface_definitions_have_comment(NULL, head->next); ck_assert_ptr_nonnull(res); ck_assert_int_eq('F', res->severity); ck_assert_int_eq(F_ID_INTERNAL, res->check_id); free_check_result(res); free_policy_node(head); } END_TEST START_TEST(test_check_type_used_but_not_required_in_if) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); head->flavor = NODE_INTERFACE_DEF; struct policy_node *cur = head->first_child = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_GEN_REQ; cur->parent = head; cur->first_child = calloc(1, sizeof(struct policy_node)); cur->first_child->parent = cur; cur = cur->first_child; cur->flavor = NODE_START_BLOCK; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->prev = cur; cur->next->parent = cur->parent; cur = cur->next; cur->flavor = NODE_DECL; struct declaration_data *data = calloc(1, sizeof(struct declaration_data)); cur->data.d_data = data; data->flavor = DECL_TYPE; data->name = strdup("bar_t"); cur = cur->parent; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->prev = cur; cur->next->parent = cur->parent; cur = cur->next; cur->flavor = NODE_AV_RULE; cur->data.av_data = make_example_av_rule(); insert_into_decl_map("foo_t", "test", DECL_TYPE); insert_into_decl_map("bar_t", "test", DECL_TYPE); insert_into_decl_map("baz_t", "test", DECL_TYPE); struct av_rule_data *av_data = cur->data.av_data; free(av_data->sources->string); av_data->sources->string = strdup("$1"); const struct check_data cdata = { NULL, NULL, FILE_IF_FILE, NULL }; struct check_result *res = check_name_used_but_not_required_in_if(&cdata, cur); ck_assert_ptr_nonnull(res); ck_assert_int_eq(W_ID_NO_REQ, res->check_id); ck_assert_str_eq("Type baz_t is used in interface but not required", res->message); free_check_result(res); free_policy_node(head); free_all_maps(); } END_TEST START_TEST (test_check_type_required_but_not_used_in_if) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); head->flavor = NODE_INTERFACE_DEF; head->data.str = strdup("interface_name"); struct policy_node *cur = head->first_child = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_GEN_REQ; cur->parent = head; cur->first_child = calloc(1, sizeof(struct policy_node)); cur->first_child->parent = cur; cur = cur->first_child; cur->flavor = NODE_START_BLOCK; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->prev = cur; cur->next->parent = cur->parent; cur = cur->next; cur->flavor = NODE_DECL; struct declaration_data *data = calloc(1, sizeof(struct declaration_data)); cur->data.d_data = data; data->flavor = DECL_TYPE; data->name = strdup("bar_t"); cur = cur->parent; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->prev = cur; cur->next->parent = cur->parent; cur = cur->next; cur->flavor = NODE_AV_RULE; cur->data.av_data = make_example_av_rule(); cur = cur->prev->first_child->next; // the declaration const struct check_data cdata = { NULL, NULL, FILE_IF_FILE, NULL }; ck_assert_ptr_null(check_name_required_but_not_used_in_if(&cdata, cur)); free(data->name); data->name = strdup("not_used_t"); struct check_result *res = check_name_required_but_not_used_in_if(&cdata, cur); ck_assert_ptr_nonnull(res); free_check_result(res); free_policy_node(head); } END_TEST START_TEST (test_system_r_exception) { insert_into_decl_map("system_r", "test", DECL_ROLE); struct policy_node *head = calloc(1, sizeof(struct policy_node)); head->flavor = NODE_INTERFACE_DEF; struct policy_node *cur = head->first_child = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_GEN_REQ; cur->parent = head; cur->first_child = calloc(1, sizeof(struct policy_node)); cur->first_child->parent = cur; cur = cur->first_child; cur->flavor = NODE_START_BLOCK; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->prev = cur; cur->next->parent = cur->parent; cur = cur->next; cur->flavor = NODE_DECL; struct declaration_data *data = calloc(1, sizeof(struct declaration_data)); cur->data.d_data = data; data->flavor = DECL_ROLE; data->name = strdup("staff_r"); cur = cur->parent; cur->next = calloc(1, sizeof(struct policy_node)); cur->next->prev = cur; cur->next->parent = cur->parent; cur = cur->next; cur->flavor = NODE_ROLE_ALLOW; cur->data.ra_data = calloc(1, sizeof(struct role_allow_data)); cur->data.ra_data->from = sl_from_str("system_r"); cur->data.ra_data->to = sl_from_str("staff_r"); const struct check_data cdata = { NULL, NULL, FILE_IF_FILE, NULL }; ck_assert_ptr_null(check_name_used_but_not_required_in_if(&cdata, cur)); free_policy_node(head); free_all_maps(); } END_TEST static Suite *if_checks_suite(void) { Suite *s; TCase *tc_core; s = suite_create("IF_Checks"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_check_interface_defs_have_comment); tcase_add_test(tc_core, test_check_type_used_but_not_required_in_if); tcase_add_test(tc_core, test_check_type_required_but_not_used_in_if); tcase_add_test(tc_core, test_system_r_exception); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = if_checks_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_parse_functions.c0000644000175100001710000003623114167117255015612 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "../src/parse_functions.h" #include "../src/maps.h" #define EXAMPLE_TYPE_1 "foo_t" #define EXAMPLE_TYPE_2 "bar_t" #define EXAMPLE_TYPE_3 "baz_t" START_TEST (test_insert_header) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_TE_FILE; ck_assert_int_eq(SELINT_SUCCESS, insert_header(&cur, "example", HEADER_BARE, 1)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_null(cur->parent); ck_assert_ptr_null(cur->next); ck_assert_ptr_nonnull(cur->prev); ck_assert_ptr_null(cur->first_child); ck_assert_int_eq(NODE_HEADER, cur->flavor); ck_assert_int_eq(cur->data.h_data->flavor, HEADER_BARE); ck_assert_str_eq(cur->data.h_data->module_name, "example"); ck_assert_int_eq(cur->lineno, 1); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(cur->prev)); cleanup_parsing(); } END_TEST START_TEST (test_insert_comment) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); cur->flavor = NODE_TE_FILE; struct policy_node *prev = cur; ck_assert_int_eq(SELINT_SUCCESS, insert_comment(&cur, 12345)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_eq(cur->prev, prev); ck_assert_int_eq(cur->flavor, NODE_COMMENT); ck_assert_int_eq(cur->lineno, 12345); ck_assert_ptr_null(cur->data.str); ck_assert_int_eq(SELINT_SUCCESS,free_policy_node(prev)); } END_TEST START_TEST (test_insert_declaration) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); cur->flavor = NODE_TE_FILE; cur->parent = NULL; cur->data.d_data = NULL; cur->first_child = NULL; cur->next = NULL; struct policy_node *prev = cur; set_current_module_name("test"); struct string_list *attrs = calloc(1, sizeof(struct string_list)); ck_assert_int_eq(SELINT_SUCCESS, insert_declaration(&cur, DECL_TYPE, "foo_t", attrs, 1234)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_null(cur->parent); ck_assert_ptr_eq(cur->prev, prev); ck_assert_int_eq(cur->flavor, NODE_DECL); ck_assert_int_eq(cur->lineno, 1234); ck_assert_ptr_null(cur->first_child); ck_assert_ptr_null(prev->first_child); ck_assert_ptr_nonnull(cur->data.d_data); ck_assert_int_eq(cur->data.d_data->flavor, DECL_TYPE); ck_assert_str_eq(cur->data.d_data->name, "foo_t"); ck_assert_ptr_eq(cur->data.d_data->attrs, attrs); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(prev)); // TODO attributes const char *mn = look_up_in_decl_map("foo_t", DECL_TYPE); ck_assert_ptr_nonnull(mn); cleanup_parsing(); } END_TEST START_TEST (test_insert_aliases) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); cur->flavor = NODE_DECL; struct policy_node *orig = cur; struct string_list *aliases = calloc(1, sizeof(struct string_list)); aliases->string = strdup("foo_t"); aliases->next = calloc(1, sizeof(struct string_list)); aliases->next->string = strdup("bar_t"); aliases->next->next = NULL; set_current_module_name("test"); ck_assert_int_eq(SELINT_SUCCESS, insert_aliases(&cur, aliases, DECL_TYPE, 123)); ck_assert_ptr_eq(cur, orig); ck_assert_ptr_nonnull(cur->first_child); cur = cur->first_child; ck_assert_int_eq(cur->flavor, NODE_ALIAS); ck_assert_str_eq(cur->data.str, "foo_t"); ck_assert_ptr_null(cur->prev); ck_assert_ptr_eq(cur->parent, orig); ck_assert_ptr_nonnull(cur->next); ck_assert_int_eq(cur->lineno, 123); cur = cur->next; ck_assert_int_eq(cur->flavor, NODE_ALIAS); ck_assert_str_eq(cur->data.str, "bar_t"); ck_assert_ptr_nonnull(cur->prev); ck_assert_ptr_eq(cur->parent, orig); ck_assert_ptr_null(cur->next); ck_assert_int_eq(cur->lineno, 123); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(orig)); ck_assert_ptr_nonnull(look_up_in_decl_map("foo_t", DECL_TYPE)); ck_assert_ptr_nonnull(look_up_in_decl_map("bar_t", DECL_TYPE)); cleanup_parsing(); } END_TEST START_TEST (test_insert_type_alias) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); struct policy_node *orig = cur; ck_assert_int_eq(SELINT_SUCCESS, insert_type_alias(&cur, "foo_t", 123)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_eq(cur->prev, orig); ck_assert_int_eq(cur->flavor, NODE_TYPE_ALIAS); ck_assert_int_eq(cur->lineno, 123); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(orig)); cleanup_parsing(); } END_TEST START_TEST (test_insert_av_rule) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); struct policy_node *head = cur; ck_assert_int_eq(SELINT_SUCCESS, insert_av_rule(&cur, AV_RULE_AUDITALLOW, NULL, NULL, NULL, NULL, 1234)); ck_assert_ptr_nonnull(cur); ck_assert_int_eq(NODE_AV_RULE, cur->flavor); struct av_rule_data *avd = cur->data.av_data; ck_assert_int_eq(AV_RULE_AUDITALLOW, avd->flavor); ck_assert_int_eq(cur->lineno, 1234); ck_assert_ptr_null(avd->sources); ck_assert_ptr_null(avd->targets); ck_assert_ptr_null(avd->object_classes); ck_assert_ptr_null(avd->perms); free_policy_node(head); cleanup_parsing(); } END_TEST START_TEST (test_insert_role_allow) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); struct policy_node *head = cur; struct string_list *sl1 = sl_from_str("staff_r"); struct string_list *sl2 = sl_from_str("dbadm_r"); ck_assert_int_eq(SELINT_SUCCESS, insert_role_allow(&cur, sl1, sl2, 20)); ck_assert_ptr_nonnull(cur); ck_assert_int_eq(NODE_ROLE_ALLOW, cur->flavor); struct role_allow_data *ra = cur->data.ra_data; ck_assert_str_eq("staff_r", ra->from->string); ck_assert_ptr_null(ra->from->next); ck_assert_str_eq("dbadm_r", ra->to->string); ck_assert_ptr_null(ra->to->next); free_policy_node(head); cleanup_parsing(); } END_TEST START_TEST (test_insert_type_transition) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); struct policy_node *head = cur; ck_assert_int_eq(SELINT_SUCCESS, insert_type_transition(&cur, TT_TT, NULL, NULL, NULL, "example_tmp_t", NULL, 1234)); ck_assert_ptr_nonnull(cur); ck_assert_int_eq(NODE_TT_RULE, cur->flavor); ck_assert_int_eq(cur->lineno, 1234); struct type_transition_data *ttd = cur->data.tt_data; ck_assert_ptr_null(ttd->sources); ck_assert_ptr_null(ttd->targets); ck_assert_ptr_null(ttd->object_classes); ck_assert_str_eq("example_tmp_t", ttd->default_type); ck_assert_ptr_null(ttd->name); free_policy_node(head); cleanup_parsing(); } END_TEST START_TEST (test_insert_named_type_transition) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); struct policy_node *head = cur; ck_assert_int_eq(SELINT_SUCCESS, insert_type_transition(&cur, TT_TT, NULL, NULL, NULL, "example_tmp_t", "filename.txt", 1234)); ck_assert_ptr_nonnull(cur); ck_assert_int_eq(NODE_TT_RULE, cur->flavor); ck_assert_int_eq(cur->lineno, 1234); struct type_transition_data *ttd = cur->data.tt_data; ck_assert_ptr_null(ttd->sources); ck_assert_ptr_null(ttd->targets); ck_assert_ptr_null(ttd->object_classes); ck_assert_str_eq("example_tmp_t", ttd->default_type); ck_assert_str_eq("filename.txt", ttd->name); free_policy_node(head); cleanup_parsing(); } END_TEST START_TEST (test_insert_interface_call) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); struct policy_node *head = cur; struct string_list *args = calloc(1, sizeof(struct string_list)); args->string = strdup("foo_t"); args->next = calloc(1, sizeof(struct string_list)); args->next->string = strdup("bar_t"); args->next->next = NULL; ck_assert_int_eq(SELINT_SUCCESS, insert_interface_call(&cur, "do_things", args, 1234)); ck_assert_ptr_nonnull(cur); ck_assert_int_eq(NODE_IF_CALL, cur->flavor); ck_assert_int_eq(cur->lineno, 1234); ck_assert_ptr_null(cur->next); ck_assert_ptr_null(cur->parent); ck_assert_ptr_null(cur->first_child); ck_assert_ptr_nonnull(cur->prev); struct if_call_data *if_data = cur->data.ic_data; ck_assert_str_eq("do_things", if_data->name); ck_assert_str_eq("foo_t", if_data->args->string); ck_assert_str_eq("bar_t", if_data->args->next->string); free_policy_node(head); cleanup_parsing(); } END_TEST START_TEST (test_insert_permissive_statement) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); struct policy_node *head = cur; ck_assert_int_eq(SELINT_SUCCESS, insert_permissive_statement(&cur, "unconfined_t", 5678)); ck_assert_ptr_nonnull(cur); ck_assert_int_eq(NODE_PERMISSIVE, cur->flavor); ck_assert_int_eq(5678, cur->lineno); ck_assert_ptr_null(cur->next); ck_assert_ptr_null(cur->parent); ck_assert_ptr_null(cur->first_child); ck_assert_ptr_eq(cur->prev, head); ck_assert_str_eq("unconfined_t", cur->data.str); free_policy_node(head); cleanup_parsing(); } END_TEST START_TEST (test_optional_policy) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); cur->flavor = NODE_TE_FILE; struct policy_node *head = cur; ck_assert_int_eq(SELINT_SUCCESS, begin_optional_policy(&cur, 1234)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_nonnull(cur->parent); ck_assert_ptr_eq(cur->parent->prev, head); ck_assert_int_eq(cur->flavor, NODE_START_BLOCK); ck_assert_int_eq(cur->parent->flavor, NODE_OPTIONAL_POLICY); ck_assert_ptr_eq(cur->parent->first_child, cur); ck_assert_int_eq(cur->lineno, 1234); ck_assert_int_eq(cur->parent->lineno, 1234); ck_assert_ptr_null(cur->next); ck_assert_ptr_null(cur->prev); ck_assert_ptr_null(cur->first_child); ck_assert_ptr_null(cur->parent->next); ck_assert_int_eq(SELINT_SUCCESS, end_optional_policy(&cur)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_eq(cur->prev, head); ck_assert_int_eq(cur->flavor, NODE_OPTIONAL_POLICY); ck_assert_ptr_nonnull(cur->first_child); ck_assert_ptr_null(cur->first_child->prev); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(head)); cleanup_parsing(); } END_TEST START_TEST (test_interface_def) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); cur->flavor = NODE_TE_FILE; struct policy_node *head = cur; set_current_module_name("test"); ck_assert_int_eq(SELINT_SUCCESS, begin_interface_def(&cur, NODE_INTERFACE_DEF, "foo_read_conf", 1234)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_nonnull(cur->parent); ck_assert_ptr_eq(cur->parent->prev, head); ck_assert_int_eq(cur->flavor, NODE_START_BLOCK); ck_assert_int_eq(cur->parent->flavor, NODE_INTERFACE_DEF); ck_assert_ptr_eq(cur->parent->first_child, cur); ck_assert_str_eq(cur->parent->data.str, "foo_read_conf"); ck_assert_int_eq(cur->lineno, 1234); ck_assert_int_eq(cur->parent->lineno, 1234); ck_assert_ptr_null(cur->next); ck_assert_ptr_null(cur->prev); ck_assert_ptr_null(cur->first_child); ck_assert_ptr_null(cur->parent->next); ck_assert_int_eq(SELINT_SUCCESS, end_interface_def(&cur)); ck_assert_int_eq(SELINT_BAD_ARG, begin_interface_def(&cur, NODE_DECL, "foo_read_conf", 2345)); ck_assert_ptr_nonnull(cur); ck_assert_ptr_eq(cur->prev, head); ck_assert_int_eq(cur->flavor, NODE_INTERFACE_DEF); ck_assert_int_eq(cur->lineno, 1234); ck_assert_ptr_nonnull(cur->first_child); ck_assert_int_eq(cur->first_child->lineno, 1234); ck_assert_ptr_null(cur->first_child->prev); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(head)); cleanup_parsing(); } END_TEST START_TEST (test_wrong_block_end) { struct policy_node *cur = malloc(sizeof(struct policy_node)); memset(cur, 0, sizeof(struct policy_node)); cur->flavor = NODE_TE_FILE; struct policy_node *head = cur; set_current_module_name("test"); ck_assert_int_eq(SELINT_SUCCESS, begin_optional_policy(&cur, 1234)); ck_assert_int_eq(SELINT_NOT_IN_BLOCK, end_interface_def(&cur)); ck_assert_int_eq(SELINT_SUCCESS, end_optional_policy(&cur)); ck_assert_int_eq(SELINT_NOT_IN_BLOCK, end_optional_policy(&cur)); ck_assert_int_eq(SELINT_SUCCESS, begin_interface_def(&cur, NODE_INTERFACE_DEF, "sample_interface", 1235)); ck_assert_int_eq(SELINT_NOT_IN_BLOCK, end_optional_policy(&cur)); ck_assert_int_eq(SELINT_NOT_IN_BLOCK, end_gen_require(&cur, 0)); ck_assert_int_eq(SELINT_SUCCESS, end_interface_def(&cur)); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(head)); cleanup_parsing(); } END_TEST START_TEST (test_save_command) { struct policy_node *cur = calloc(1, sizeof(struct policy_node)); ck_assert_int_eq(SELINT_BAD_ARG, save_command(NULL, "foo")); ck_assert_int_eq(SELINT_SUCCESS, save_command(cur, NULL)); ck_assert_int_eq(SELINT_PARSE_ERROR, save_command(cur, "foo")); ck_assert_int_eq(SELINT_PARSE_ERROR, save_command(cur, "selint-fake:W-001")); ck_assert_ptr_null(cur->exceptions); ck_assert_int_eq(SELINT_SUCCESS, save_command(cur, "selint-disable:W-001")); ck_assert_str_eq("W-001", cur->exceptions); ck_assert_int_eq(SELINT_SUCCESS, free_policy_node(cur)); cleanup_parsing(); } END_TEST START_TEST (test_insert_type_attribute) { struct policy_node *head = calloc(1, sizeof(struct policy_node)); struct policy_node *cur = head; struct string_list *attrs = calloc(1, sizeof(struct string_list)); attrs->string = strdup("foo"); ck_assert_int_eq(SELINT_SUCCESS, insert_type_attribute(&cur, "foo_t", attrs, 1234)); ck_assert_ptr_eq(cur->prev, head); ck_assert_str_eq(cur->data.at_data->type, "foo_t"); ck_assert_str_eq(cur->data.at_data->attrs->string, "foo"); free_policy_node(head); cleanup_parsing(); } END_TEST static Suite *parse_functions_suite(void) { Suite *s; TCase *tc_core, *tc_blocks; s = suite_create("Parse_Functions"); tc_core = tcase_create("Core"); tc_blocks = tcase_create("Blocks"); tcase_add_test(tc_core, test_insert_header); tcase_add_test(tc_core, test_insert_comment); tcase_add_test(tc_core, test_insert_declaration); tcase_add_test(tc_core, test_insert_aliases); tcase_add_test(tc_core, test_insert_type_alias); tcase_add_test(tc_core, test_insert_av_rule); tcase_add_test(tc_core, test_insert_role_allow); tcase_add_test(tc_core, test_insert_type_transition); tcase_add_test(tc_core, test_insert_named_type_transition); tcase_add_test(tc_core, test_insert_interface_call); tcase_add_test(tc_core, test_insert_permissive_statement); tcase_add_test(tc_core, test_save_command); tcase_add_test(tc_core, test_insert_type_attribute); suite_add_tcase(s, tc_core); tcase_add_test(tc_blocks, test_optional_policy); tcase_add_test(tc_blocks, test_interface_def); tcase_add_test(tc_blocks, test_wrong_block_end); suite_add_tcase(s, tc_blocks); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = parse_functions_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_maps.c0000644000175100001710000001660314167117255013351 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "../src/maps.h" START_TEST (test_insert_into_type_map) { insert_into_decl_map("foo_t", "test_module", DECL_TYPE); insert_into_decl_map("bar_t", "test_module", DECL_TYPE); insert_into_decl_map("baz_t", "other_module", DECL_TYPE); const char *mod_name = look_up_in_decl_map("doesntexist", DECL_TYPE); ck_assert_ptr_null(mod_name); mod_name = look_up_in_decl_map("foo_t", DECL_TYPE); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq(mod_name, "test_module"); mod_name = look_up_in_decl_map("bar_t", DECL_TYPE); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq(mod_name, "test_module"); mod_name = look_up_in_decl_map("baz_t", DECL_TYPE); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq(mod_name, "other_module"); ck_assert_int_eq(decl_map_count(DECL_TYPE), 3); free_all_maps(); } END_TEST START_TEST (test_insert_into_type_map_dup) { insert_into_decl_map("foo_t", "test_module", DECL_TYPE); insert_into_decl_map("foo_t", "other_module", DECL_TYPE); ck_assert_int_eq(decl_map_count(DECL_TYPE), 1); free_all_maps(); } END_TEST START_TEST (test_role_and_user_maps) { insert_into_decl_map("foo_r", "test_module1", DECL_ROLE); insert_into_decl_map("bar_r", "test_module2", DECL_ROLE); insert_into_decl_map("bar_u", "test_module3", DECL_USER); const char *mod_name = look_up_in_decl_map("foo_r", DECL_TYPE); ck_assert_ptr_null(mod_name); mod_name = look_up_in_decl_map("foo_r", DECL_ROLE); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq(mod_name, "test_module1"); mod_name = look_up_in_decl_map("foo_r", DECL_ATTRIBUTE); ck_assert_ptr_null(mod_name); mod_name = look_up_in_decl_map("bar_u", DECL_ROLE); ck_assert_ptr_null(mod_name); mod_name = look_up_in_decl_map("bar_u", DECL_USER); ck_assert_ptr_nonnull(mod_name); ck_assert_str_eq(mod_name, "test_module3"); ck_assert_int_eq(decl_map_count(DECL_TYPE), 0); ck_assert_int_eq(decl_map_count(DECL_ROLE), 2); ck_assert_int_eq(decl_map_count(DECL_USER), 1); free_all_maps(); } END_TEST START_TEST (test_class_and_perm_maps) { insert_into_decl_map("file", "class", DECL_CLASS); insert_into_decl_map("read", "perm", DECL_PERM); const char *res = look_up_in_decl_map("dir", DECL_CLASS); ck_assert_ptr_null(res); res = look_up_in_decl_map("file", DECL_CLASS); ck_assert_ptr_nonnull(res); res = look_up_in_decl_map("read", DECL_PERM); ck_assert_ptr_nonnull(res); ck_assert_int_eq(decl_map_count(DECL_CLASS), 1); ck_assert_int_eq(decl_map_count(DECL_PERM), 1); free_all_maps(); } END_TEST START_TEST (test_mods_map) { insert_into_mods_map("systemd", "base"); insert_into_mods_map("games", "off"); const char *res = look_up_in_mods_map("systemd"); ck_assert_str_eq("base", res); res = look_up_in_mods_map("games"); ck_assert_str_eq("off", res); res = look_up_in_mods_map("foo"); ck_assert_ptr_null(res); free_all_maps(); } END_TEST START_TEST (test_insert_decl_into_template_map) { insert_decl_into_template_map("user_domain", DECL_TYPE, "$1_t"); insert_decl_into_template_map("user_domain", DECL_TYPE, "$1_exec_t"); insert_decl_into_template_map("user_domain", DECL_ROLE, "$1_r"); insert_decl_into_template_map("other_template", DECL_TYPE, "$1_conf_t"); const struct decl_list *dl = look_up_decl_in_template_map("doesntexist"); ck_assert_ptr_null(dl); dl = look_up_decl_in_template_map("user_domain"); ck_assert_ptr_nonnull(dl); ck_assert_ptr_nonnull(dl->decl); ck_assert_int_eq(dl->decl->flavor, DECL_TYPE); ck_assert_ptr_nonnull(dl->decl->name); ck_assert_str_eq(dl->decl->name, "$1_t"); ck_assert_ptr_null(dl->decl->attrs); dl = dl->next; ck_assert_ptr_nonnull(dl); ck_assert_ptr_nonnull(dl->decl); ck_assert_int_eq(dl->decl->flavor, DECL_TYPE); ck_assert_ptr_nonnull(dl->decl->name); ck_assert_str_eq(dl->decl->name, "$1_exec_t"); ck_assert_ptr_null(dl->decl->attrs); dl = dl->next; ck_assert_ptr_nonnull(dl); ck_assert_ptr_nonnull(dl->decl); ck_assert_int_eq(dl->decl->flavor, DECL_ROLE); ck_assert_ptr_nonnull(dl->decl->name); ck_assert_str_eq(dl->decl->name, "$1_r"); ck_assert_ptr_null(dl->decl->attrs); ck_assert_ptr_null(dl->next); dl = look_up_decl_in_template_map("other_template"); ck_assert_ptr_nonnull(dl); ck_assert_ptr_nonnull(dl->decl); ck_assert_int_eq(dl->decl->flavor, DECL_TYPE); ck_assert_ptr_nonnull(dl->decl->name); ck_assert_str_eq(dl->decl->name, "$1_conf_t"); ck_assert_ptr_null(dl->decl->attrs); free_all_maps(); } END_TEST START_TEST (test_insert_call_into_template_map) { struct if_call_data *call = malloc(sizeof(struct if_call_data)); call->name = strdup("foo"); call->args = calloc(1, sizeof(struct string_list)); call->args->string = strdup("bar_t"); call->args->next = NULL; insert_call_into_template_map("user_domain", call); insert_decl_into_template_map("user_domain", DECL_TYPE, "$1_conf_t"); const struct if_call_list *out = look_up_call_in_template_map("user_domain"); ck_assert_ptr_eq(call, out->call); free_if_call_data(call); } END_TEST static size_t test_permmacro_map_count = 0; static void test_permmacro_map_visitor(const char *key, const struct string_list *val) { test_permmacro_map_count += strlen(key); test_permmacro_map_count += strlen(val->string); } START_TEST (test_permmacro_map) { struct string_list *sl1 = sl_from_str("test"); ck_assert_ptr_nonnull(sl1); struct string_list *sl2 = sl_from_strs(3, "hello", "world", "!"); ck_assert_ptr_nonnull(sl2); insert_into_permmacros_map("test", sl1); // consumes sl1 insert_into_permmacros_map("standard", sl2); // consumes sl2 ck_assert_ptr_null(look_up_in_permmacros_map("hello")); ck_assert_ptr_null(look_up_in_permmacros_map("Test")); const struct string_list *csl = look_up_in_permmacros_map("standard"); ck_assert_ptr_nonnull(csl); ck_assert_str_eq("hello", csl->string); ck_assert_ptr_nonnull(csl->next); ck_assert_str_eq("world", csl->next->string); visit_all_in_permmacros_map(test_permmacro_map_visitor); ck_assert_uint_eq(2 * strlen("test") + strlen("standard") + strlen("hello"), test_permmacro_map_count); free_all_maps(); } END_TEST static Suite *maps_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Maps"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_insert_into_type_map); tcase_add_test(tc_core, test_insert_into_type_map_dup); tcase_add_test(tc_core, test_role_and_user_maps); tcase_add_test(tc_core, test_class_and_perm_maps); tcase_add_test(tc_core, test_mods_map); tcase_add_test(tc_core, test_insert_decl_into_template_map); tcase_add_test(tc_core, test_insert_call_into_template_map); tcase_add_test(tc_core, test_permmacro_map); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = maps_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/check_string_list.c0000644000175100001710000001355714167117255014757 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "../src/string_list.h" START_TEST (test_str_in_sl) { struct string_list *sl = calloc(1, sizeof(struct string_list)); sl->string = strdup("foo"); sl->next = calloc(1, sizeof(struct string_list)); sl->next->string = strdup("bar"); ck_assert_int_eq(1, str_in_sl("foo", sl)); ck_assert_int_eq(1, str_in_sl("bar", sl)); ck_assert_int_eq(0, str_in_sl("baz", sl)); ck_assert_int_eq(0, str_in_sl("foo", NULL)); free_string_list(sl); } END_TEST START_TEST (test_copy_string_list) { struct string_list *cur; struct string_list *sl1 = calloc(1, sizeof(struct string_list)); sl1->string = strdup("foo"); sl1->next = calloc(1, sizeof(struct string_list)); cur = sl1->next; cur->string = strdup("bar"); cur->has_incorrect_space = 1; cur->next = calloc(1,sizeof(struct string_list)); cur = cur->next; cur->string = strdup("baz"); struct string_list *sl2 = copy_string_list(sl1); ck_assert_ptr_nonnull(sl2); ck_assert_ptr_ne(sl1, sl2); ck_assert_str_eq(sl1->string, sl2->string); ck_assert_ptr_ne(sl1->string, sl2->string); ck_assert_int_eq(sl1->has_incorrect_space, sl2->has_incorrect_space); ck_assert_ptr_ne(sl1->next, sl2->next); ck_assert_ptr_nonnull(sl2->next); ck_assert_str_eq(sl1->next->string, sl2->next->string); ck_assert_ptr_ne(sl1->next->string, sl2->next->string); ck_assert_int_eq(sl1->next->has_incorrect_space, sl2->next->has_incorrect_space); ck_assert_ptr_ne(sl1->next->next, sl2->next->next); ck_assert_ptr_nonnull(sl2->next->next); ck_assert_str_eq(sl1->next->next->string, sl2->next->next->string); ck_assert_ptr_null(sl2->next->next->next); free_string_list(sl1); free_string_list(sl2); } END_TEST START_TEST (test_copy_string_list_null) { ck_assert_ptr_null(copy_string_list(NULL)); } END_TEST START_TEST (test_sl_from_str) { struct string_list *sl = sl_from_str("test"); ck_assert_ptr_nonnull(sl); ck_assert_str_eq("test", sl->string); ck_assert_int_eq(0, sl->has_incorrect_space); ck_assert_ptr_null(sl->next); free_string_list(sl); } END_TEST START_TEST (test_sl_from_strn) { struct string_list *sl = sl_from_strn("hello world", 5); ck_assert_ptr_nonnull(sl); ck_assert_str_eq("hello", sl->string); ck_assert_int_eq(0, sl->has_incorrect_space); ck_assert_ptr_null(sl->next); free_string_list(sl); sl = sl_from_strn("hello world", 0); ck_assert_ptr_nonnull(sl); ck_assert_str_eq("", sl->string); ck_assert_int_eq(0, sl->has_incorrect_space); ck_assert_ptr_null(sl->next); free_string_list(sl); } END_TEST START_TEST (test_sl_from_strs) { struct string_list *sl = sl_from_strs(2, "hello", "world"); ck_assert_ptr_nonnull(sl); ck_assert_str_eq("hello", sl->string); ck_assert_int_eq(0, sl->has_incorrect_space); ck_assert_ptr_nonnull(sl->next); ck_assert_str_eq("world", sl->next->string); ck_assert_int_eq(0, sl->next->has_incorrect_space); ck_assert_ptr_null(sl->next->next); free_string_list(sl); } END_TEST START_TEST (test_concat_string_lists) { struct string_list *res, *sl1, *sl2; ck_assert_ptr_null(concat_string_lists(NULL, NULL)); sl1 = sl_from_str("hello"); ck_assert_ptr_nonnull(sl1); sl2 = sl_from_str("world"); ck_assert_ptr_nonnull(sl2); res = concat_string_lists(NULL, sl1); ck_assert_ptr_nonnull(res); ck_assert_str_eq("hello", res->string); ck_assert_int_eq(0, res->has_incorrect_space); ck_assert_ptr_null(res->next); res = concat_string_lists(sl1, NULL); ck_assert_ptr_nonnull(res); ck_assert_str_eq("hello", res->string); ck_assert_int_eq(0, res->has_incorrect_space); ck_assert_ptr_null(res->next); res = concat_string_lists(sl1, sl2); ck_assert_ptr_nonnull(res); ck_assert_str_eq("hello", res->string); ck_assert_int_eq(0, res->has_incorrect_space); ck_assert_ptr_nonnull(res->next); ck_assert_str_eq("world", res->next->string); ck_assert_int_eq(0, res->next->has_incorrect_space); ck_assert_ptr_null(res->next->next); free_string_list(res); // frees sl1 and sl2 } END_TEST START_TEST (test_append_to_sl) { struct string_list *list = NULL; ck_assert_int_eq(SELINT_BAD_ARG, append_to_sl(list, "test")); list = sl_from_str("test1"); ck_assert_int_eq(SELINT_SUCCESS, append_to_sl(list, "test2")); ck_assert_int_eq(SELINT_SUCCESS, append_to_sl(list, "test3")); ck_assert_str_eq(list->string, "test1"); ck_assert_ptr_nonnull(list->next); ck_assert_str_eq(list->next->string, "test2"); ck_assert_ptr_nonnull(list->next->next); ck_assert_str_eq(list->next->next->string, "test3"); ck_assert_ptr_null(list->next->next->next); free_string_list(list); } END_TEST static Suite *string_list_suite(void) { Suite *s; TCase *tc_core; s = suite_create("String_list"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_str_in_sl); tcase_add_test(tc_core, test_copy_string_list); tcase_add_test(tc_core, test_copy_string_list_null); tcase_add_test(tc_core, test_sl_from_str); tcase_add_test(tc_core, test_sl_from_strn); tcase_add_test(tc_core, test_sl_from_strs); tcase_add_test(tc_core, test_concat_string_lists); tcase_add_test(tc_core, test_append_to_sl); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = string_list_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/tests/Makefile.in0000644000175100001710000020764714167117365013171 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : TESTS = check_tree$(EXEEXT) check_parse_functions$(EXEEXT) \ check_maps$(EXEEXT) check_parsing$(EXEEXT) \ check_parse_fc$(EXEEXT) check_template$(EXEEXT) \ check_file_list$(EXEEXT) check_fc_checks$(EXEEXT) \ check_check_hooks$(EXEEXT) check_selint_config$(EXEEXT) \ check_if_checks$(EXEEXT) check_string_list$(EXEEXT) \ check_runner$(EXEEXT) check_startup$(EXEEXT) \ check_te_checks$(EXEEXT) check_ordering$(EXEEXT) \ check_perm_macro$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) @COND_GCOV_TRUE@am__append_1 = --coverage -fno-inline -fno-inline-small-functions -fno-default-inline subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = check_tree$(EXEEXT) check_parse_functions$(EXEEXT) \ check_maps$(EXEEXT) check_parsing$(EXEEXT) \ check_parse_fc$(EXEEXT) check_template$(EXEEXT) \ check_file_list$(EXEEXT) check_fc_checks$(EXEEXT) \ check_check_hooks$(EXEEXT) check_selint_config$(EXEEXT) \ check_if_checks$(EXEEXT) check_string_list$(EXEEXT) \ check_runner$(EXEEXT) check_startup$(EXEEXT) \ check_te_checks$(EXEEXT) check_ordering$(EXEEXT) \ check_perm_macro$(EXEEXT) am__objects_1 = am__objects_2 = $(am__objects_1) am__objects_3 = $(am__objects_2) am__objects_4 = $(am__objects_1) $(am__objects_1) $(am__objects_3) am_check_check_hooks_OBJECTS = check_check_hooks.$(OBJEXT) \ $(am__objects_4) check_check_hooks_OBJECTS = $(am_check_check_hooks_OBJECTS) check_check_hooks_DEPENDENCIES = $(sort ${CHECK_HOOKS_OBJS}) am__objects_5 = $(am__objects_4) am__objects_6 = $(am__objects_1) $(am__objects_3) am_check_fc_checks_OBJECTS = check_fc_checks.$(OBJEXT) \ $(am__objects_5) $(am__objects_4) $(am__objects_6) check_fc_checks_OBJECTS = $(am_check_fc_checks_OBJECTS) am__DEPENDENCIES_1 = $(top_builddir)/src/tree.o $(STRING_LIST_OBJS) \ $(top_builddir)/src/maps.o am__DEPENDENCIES_2 = $(top_builddir)/src/check_hooks.o $(COLOR_OBJS) \ $(am__DEPENDENCIES_1) am__DEPENDENCIES_3 = $(top_builddir)/src/fc_checks.o \ $(am__DEPENDENCIES_2) am__DEPENDENCIES_4 = $(top_builddir)/src/maps.o $(am__DEPENDENCIES_1) check_fc_checks_DEPENDENCIES = $(sort $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_4) ${UTIL_OBJS}) am__objects_7 = $(am__objects_3) am_check_file_list_OBJECTS = check_file_list.$(OBJEXT) \ $(am__objects_7) check_file_list_OBJECTS = $(am_check_file_list_OBJECTS) check_file_list_DEPENDENCIES = $(sort ${FILE_LIST_OBJS}) am__objects_8 = $(am__objects_4) $(am__objects_1) am_check_if_checks_OBJECTS = check_if_checks.$(OBJEXT) \ test_utils.$(OBJEXT) $(am__objects_8) $(am__objects_4) \ $(am__objects_6) $(am__objects_1) check_if_checks_OBJECTS = $(am_check_if_checks_OBJECTS) am__DEPENDENCIES_5 = $(top_builddir)/src/if_checks.o \ $(am__DEPENDENCIES_2) $(UTIL_OBJS) check_if_checks_DEPENDENCIES = $(sort $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_4) \ ${TEST_UTILS_OBJS}) am_check_maps_OBJECTS = check_maps.$(OBJEXT) $(am__objects_6) check_maps_OBJECTS = $(am_check_maps_OBJECTS) check_maps_DEPENDENCIES = $(sort ${MAPS_OBJS}) am__objects_9 = $(am__objects_1) $(am__objects_1) am__objects_10 = $(am__objects_1) $(am__objects_3) $(am__objects_6) \ $(am__objects_9) am__objects_11 = $(am__objects_1) $(am__objects_4) $(am__objects_10) \ $(am__objects_7) am_check_ordering_OBJECTS = check_ordering.$(OBJEXT) $(am__objects_6) \ $(am__objects_11) $(am__objects_6) check_ordering_OBJECTS = $(am_check_ordering_OBJECTS) am__DEPENDENCIES_6 = $(top_builddir)/src/ordering.o \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) am__DEPENDENCIES_7 = $(top_builddir)/src/template.o \ $(am__DEPENDENCIES_1) am__DEPENDENCIES_8 = $(top_builddir)/src/perm_macro.o $(UTIL_OBJS) \ $(COLOR_OBJS) am__DEPENDENCIES_9 = $(top_builddir)/src/parse_functions.o \ $(am__DEPENDENCIES_7) $(am__DEPENDENCIES_6) \ $(am__DEPENDENCIES_8) am__DEPENDENCIES_10 = $(top_builddir)/src/file_list.o \ $(am__DEPENDENCIES_1) am__DEPENDENCIES_11 = $(top_builddir)/src/te_checks.o \ $(am__DEPENDENCIES_2) $(top_builddir)/src/ordering.o \ $(UTIL_OBJS) am__DEPENDENCIES_12 = $(top_builddir)/src/parse_fc.o \ $(am__DEPENDENCIES_1) am__DEPENDENCIES_13 = $(top_builddir)/src/parse.o \ $(top_builddir)/src/lex.o $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_9) am__DEPENDENCIES_14 = $(top_builddir)/src/startup.o \ $(am__DEPENDENCIES_10) $(am__DEPENDENCIES_13) am__DEPENDENCIES_15 = $(top_builddir)/src/runner.o \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_9) \ $(am__DEPENDENCIES_10) $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_11) \ $(am__DEPENDENCIES_12) $(UTIL_OBJS) $(am__DEPENDENCIES_14) \ $(am__DEPENDENCIES_13) check_ordering_DEPENDENCIES = $(sort $(am__DEPENDENCIES_6) \ $(am__DEPENDENCIES_15) ${MAPS_OBJS}) am_check_parse_fc_OBJECTS = check_parse_fc.$(OBJEXT) $(am__objects_7) \ $(am__objects_3) check_parse_fc_OBJECTS = $(am_check_parse_fc_OBJECTS) check_parse_fc_DEPENDENCIES = $(sort $(am__DEPENDENCIES_12) \ ${TREE_OBJS}) am__objects_12 = $(am__objects_10) am_check_parse_functions_OBJECTS = check_parse_functions.$(OBJEXT) \ $(am__objects_10) $(am__objects_6) $(am__objects_12) \ $(am__objects_1) check_parse_functions_OBJECTS = $(am_check_parse_functions_OBJECTS) check_parse_functions_DEPENDENCIES = $(sort $(am__DEPENDENCIES_9) \ $(am__DEPENDENCIES_4) ${PARSE_OBJS}) am_check_parsing_OBJECTS = check_parsing.$(OBJEXT) $(am__objects_12) \ $(am__objects_3) $(am__objects_10) $(am__objects_1) check_parsing_OBJECTS = $(am_check_parsing_OBJECTS) check_parsing_DEPENDENCIES = $(sort $(am__DEPENDENCIES_13) \ $(am__DEPENDENCIES_1) ${PARSE_FUNCTIONS_OBJS}) am__objects_13 = $(am__objects_1) $(am__objects_7) $(am__objects_12) am_check_perm_macro_OBJECTS = check_perm_macro.$(OBJEXT) \ $(am__objects_9) $(am__objects_13) $(am__objects_1) \ $(am__objects_6) check_perm_macro_OBJECTS = $(am_check_perm_macro_OBJECTS) check_perm_macro_DEPENDENCIES = $(sort $(am__DEPENDENCIES_8) \ $(am__DEPENDENCIES_14) ${MAPS_OBJS}) am_check_runner_OBJECTS = check_runner.$(OBJEXT) $(am__objects_2) \ $(am__objects_11) check_runner_OBJECTS = $(am_check_runner_OBJECTS) check_runner_DEPENDENCIES = $(sort $(STRING_LIST_OBJS) ${RUNNER_OBJS}) am__objects_14 = $(am__objects_2) $(am__objects_3) $(am__objects_6) \ $(am__objects_6) am_check_selint_config_OBJECTS = check_selint_config.$(OBJEXT) \ $(am__objects_14) $(am__objects_2) check_selint_config_OBJECTS = $(am_check_selint_config_OBJECTS) am__DEPENDENCIES_16 = $(top_builddir)/src/selint_config.o \ $(STRING_LIST_OBJS) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_4) $(UTIL_OBJS) check_selint_config_DEPENDENCIES = $(sort $(am__DEPENDENCIES_16) \ ${STRING_LIST_OBJS}) am_check_startup_OBJECTS = check_startup.$(OBJEXT) $(am__objects_13) \ $(am__objects_6) $(am__objects_1) check_startup_OBJECTS = $(am_check_startup_OBJECTS) check_startup_DEPENDENCIES = $(sort $(am__DEPENDENCIES_14) \ ${MAPS_OBJS}) am_check_string_list_OBJECTS = check_string_list.$(OBJEXT) \ $(am__objects_2) check_string_list_OBJECTS = $(am_check_string_list_OBJECTS) check_string_list_DEPENDENCIES = $(sort ${STRING_LIST_OBJS}) am_check_te_checks_OBJECTS = check_te_checks.$(OBJEXT) \ test_utils.$(OBJEXT) $(am__objects_8) $(am__objects_4) \ $(am__objects_6) $(am__objects_1) $(am__objects_9) check_te_checks_OBJECTS = $(am_check_te_checks_OBJECTS) check_te_checks_DEPENDENCIES = $(sort $(am__DEPENDENCIES_11) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_4) $(TEST_UTILS_OBJS) \ ${PERM_MACRO_OBJS}) am_check_template_OBJECTS = check_template.$(OBJEXT) $(am__objects_10) \ $(am__objects_6) $(am__objects_12) $(am__objects_6) check_template_OBJECTS = $(am_check_template_OBJECTS) check_template_DEPENDENCIES = $(sort $(am__DEPENDENCIES_9) \ $(am__DEPENDENCIES_7) $(am__DEPENDENCIES_13) ${MAPS_OBJS}) am_check_tree_OBJECTS = check_tree.$(OBJEXT) test_utils.$(OBJEXT) \ $(am__objects_3) $(am__objects_1) check_tree_OBJECTS = $(am_check_tree_OBJECTS) check_tree_DEPENDENCIES = $(sort $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_4) ${TEST_UTILS_OBJS}) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/check_check_hooks.Po \ ./$(DEPDIR)/check_fc_checks.Po ./$(DEPDIR)/check_file_list.Po \ ./$(DEPDIR)/check_if_checks.Po ./$(DEPDIR)/check_maps.Po \ ./$(DEPDIR)/check_ordering.Po ./$(DEPDIR)/check_parse_fc.Po \ ./$(DEPDIR)/check_parse_functions.Po \ ./$(DEPDIR)/check_parsing.Po ./$(DEPDIR)/check_perm_macro.Po \ ./$(DEPDIR)/check_runner.Po ./$(DEPDIR)/check_selint_config.Po \ ./$(DEPDIR)/check_startup.Po ./$(DEPDIR)/check_string_list.Po \ ./$(DEPDIR)/check_te_checks.Po ./$(DEPDIR)/check_template.Po \ ./$(DEPDIR)/check_tree.Po ./$(DEPDIR)/test_utils.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(check_check_hooks_SOURCES) $(check_fc_checks_SOURCES) \ $(check_file_list_SOURCES) $(check_if_checks_SOURCES) \ $(check_maps_SOURCES) $(check_ordering_SOURCES) \ $(check_parse_fc_SOURCES) $(check_parse_functions_SOURCES) \ $(check_parsing_SOURCES) $(check_perm_macro_SOURCES) \ $(check_runner_SOURCES) $(check_selint_config_SOURCES) \ $(check_startup_SOURCES) $(check_string_list_SOURCES) \ $(check_te_checks_SOURCES) $(check_template_SOURCES) \ $(check_tree_SOURCES) DIST_SOURCES = $(check_check_hooks_SOURCES) $(check_fc_checks_SOURCES) \ $(check_file_list_SOURCES) $(check_if_checks_SOURCES) \ $(check_maps_SOURCES) $(check_ordering_SOURCES) \ $(check_parse_fc_SOURCES) $(check_parse_functions_SOURCES) \ $(check_parsing_SOURCES) $(check_perm_macro_SOURCES) \ $(check_runner_SOURCES) $(check_selint_config_SOURCES) \ $(check_startup_SOURCES) $(check_string_list_SOURCES) \ $(check_te_checks_SOURCES) $(check_template_SOURCES) \ $(check_tree_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ @CHECK_CFLAGS@ \ -DSAMPLE_POL_DIR="\"$(srcdir)/sample_policy_files/\"" \ -DSAMPLE_CONF_DIR="\"$(srcdir)/sample_configs/\"" \ -DSAMPLE_AV_DIR="\"$(srcdir)/sample_av/\"" $(am__append_1) AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_VALGRIND_drd = @ENABLE_VALGRIND_drd@ ENABLE_VALGRIND_helgrind = @ENABLE_VALGRIND_helgrind@ ENABLE_VALGRIND_memcheck = @ENABLE_VALGRIND_memcheck@ ENABLE_VALGRIND_sgcheck = @ENABLE_VALGRIND_sgcheck@ EXEEXT = @EXEEXT@ GREP = @GREP@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGES = @MANPAGES@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VALGRIND_ENABLED = @VALGRIND_ENABLED@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ valgrind_enabled_tools = @valgrind_enabled_tools@ valgrind_tools = @valgrind_tools@ VALGRIND_memcheck_FLAGS = --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all AV_FILE_PERM_FILES = sample_av/file/index \ sample_av/file/perms/append \ sample_av/file/perms/audit_access \ sample_av/file/perms/create \ sample_av/file/perms/entrypoint \ sample_av/file/perms/execmod \ sample_av/file/perms/execute \ sample_av/file/perms/execute_no_trans \ sample_av/file/perms/getattr \ sample_av/file/perms/ioctl \ sample_av/file/perms/link \ sample_av/file/perms/lock \ sample_av/file/perms/map \ sample_av/file/perms/mounton \ sample_av/file/perms/open \ sample_av/file/perms/quotaon \ sample_av/file/perms/read \ sample_av/file/perms/relabelfrom \ sample_av/file/perms/relabelto \ sample_av/file/perms/rename \ sample_av/file/perms/setattr \ sample_av/file/perms/swapon \ sample_av/file/perms/unlink \ sample_av/file/perms/write AV_SOCKET_PERM_FILES = sample_av/socket/index \ sample_av/socket/perms/accept \ sample_av/socket/perms/append \ sample_av/socket/perms/bind \ sample_av/socket/perms/connect \ sample_av/socket/perms/create \ sample_av/socket/perms/getattr \ sample_av/socket/perms/getopt \ sample_av/socket/perms/ioctl \ sample_av/socket/perms/listen \ sample_av/socket/perms/lock \ sample_av/socket/perms/map \ sample_av/socket/perms/name_bind \ sample_av/socket/perms/read \ sample_av/socket/perms/recvfrom \ sample_av/socket/perms/recv_msg \ sample_av/socket/perms/relabelfrom \ sample_av/socket/perms/relabelto \ sample_av/socket/perms/send_msg \ sample_av/socket/perms/sendto \ sample_av/socket/perms/setattr \ sample_av/socket/perms/setopt \ sample_av/socket/perms/shutdown \ sample_av/socket/perms/write AV_X_CURSOR_PERM_FILES = sample_av/x_cursor/index \ sample_av/x_cursor/perms/create \ sample_av/x_cursor/perms/destroy \ sample_av/x_cursor/perms/getattr \ sample_av/x_cursor/perms/read \ sample_av/x_cursor/perms/setattr \ sample_av/x_cursor/perms/use \ sample_av/x_cursor/perms/write SAMPLE_CONFIG_FILES = sample_configs/bad_format_2.conf \ sample_configs/bad_format.conf \ sample_configs/check_config.conf \ sample_configs/invalid_option.conf \ sample_configs/severity_convention.conf \ sample_configs/severity_error.conf \ sample_configs/severity_fatal.conf \ sample_configs/severity_invalid.conf \ sample_configs/severity_style.conf \ sample_configs/severity_warning.conf \ sample_configs/bad_order.conf \ sample_configs/refpolicy_ordering.conf \ sample_configs/order_requires.conf SAMPLE_POLICY_FILES = sample_policy_files/access_vectors \ sample_policy_files/bad_modules.conf \ sample_policy_files/bad_obj_perm_sets.spt \ sample_policy_files/bad_role_allow.te \ sample_policy_files/basic.fc \ sample_policy_files/basic.if \ sample_policy_files/basic.te \ sample_policy_files/blocks.te \ sample_policy_files/bool_declarations.te \ sample_policy_files/declaring_template.if \ sample_policy_files/declaring_template.te \ sample_policy_files/disable_comment.if \ sample_policy_files/disable_comment.te \ sample_policy_files/empty.te \ sample_policy_files/extended_perms.te \ sample_policy_files/ifdef_block.te \ sample_policy_files/modules.conf \ sample_policy_files/nested_templates.if \ sample_policy_files/none_context.fc \ sample_policy_files/obj_perm_sets.spt \ sample_policy_files/perms.spt \ sample_policy_files/syntax_error.te \ sample_policy_files/uncommon.te \ sample_policy_files/with_m4.fc FUNCTIONAL_TEST_FILES = functional/end-to-end.bats \ functional/configs/bad_ids.conf \ functional/configs/broken.conf \ functional/configs/default.conf \ functional/configs/empty.conf \ functional/configs/fc_macros.conf \ functional/configs/order_ref.conf \ functional/configs/order_lax.conf \ functional/policies/check_triggers/access_vectors \ functional/policies/check_triggers/c04.if \ functional/policies/check_triggers/c05.if \ functional/policies/check_triggers/c05.te \ functional/policies/check_triggers/c06.pass.if \ functional/policies/check_triggers/c06.warn.if \ functional/policies/check_triggers/c07.te \ functional/policies/check_triggers/c07.if \ functional/policies/check_triggers/e02.fc \ functional/policies/check_triggers/e03e04e05.fc \ functional/policies/check_triggers/e06.te \ functional/policies/check_triggers/e06.if \ functional/policies/check_triggers/e07.pass.te \ functional/policies/check_triggers/e07.warn.te \ functional/policies/check_triggers/e08.pass.te \ functional/policies/check_triggers/e08.warn.te \ functional/policies/check_triggers/e09.te \ functional/policies/check_triggers/e10.pass.te \ functional/policies/check_triggers/e10.warn.te \ functional/policies/check_triggers/modules.conf \ functional/policies/check_triggers/obj_perm_sets.spt \ functional/policies/check_triggers/s01.te \ functional/policies/check_triggers/s02.fc \ functional/policies/check_triggers/s02_other.te \ functional/policies/check_triggers/s03.te \ functional/policies/check_triggers/s04.if \ functional/policies/check_triggers/s05.if \ functional/policies/check_triggers/s06.te \ functional/policies/check_triggers/s07.fc \ functional/policies/check_triggers/s08.if \ functional/policies/check_triggers/s09.pass.te \ functional/policies/check_triggers/s09.warn.te \ functional/policies/check_triggers/w01_other.te \ functional/policies/check_triggers/w01.te \ functional/policies/check_triggers/w02.if \ functional/policies/check_triggers/w02_role.if \ functional/policies/check_triggers/w02_role.te \ functional/policies/check_triggers/w02.te \ functional/policies/check_triggers/w03_alias.if \ functional/policies/check_triggers/w03.if \ functional/policies/check_triggers/w03_role.if \ functional/policies/check_triggers/w03_stub.if \ functional/policies/check_triggers/w03_ta.if \ functional/policies/check_triggers/w04.fc \ functional/policies/check_triggers/w05_other.if \ functional/policies/check_triggers/w05.te \ functional/policies/check_triggers/w06.if \ functional/policies/check_triggers/w07.if \ functional/policies/check_triggers/w07.0.te \ functional/policies/check_triggers/w07.1.te \ functional/policies/check_triggers/w08.1.te \ functional/policies/check_triggers/w08.2.te \ functional/policies/check_triggers/w09.te \ functional/policies/check_triggers/w10.pass.te \ functional/policies/check_triggers/w10.warn.te \ functional/policies/check_triggers/w11.te \ functional/policies/check_triggers/w11.if \ functional/policies/check_triggers/C-001/interleaved.expect.ref \ functional/policies/check_triggers/C-001/interleaved.expect.lax \ functional/policies/check_triggers/C-001/interleaved.te \ functional/policies/check_triggers/C-001/if_in_optional.expect.ref \ functional/policies/check_triggers/C-001/if_in_optional.expect.lax \ functional/policies/check_triggers/C-001/if_in_optional.te \ functional/policies/check_triggers/C-001/kernel_module_first.expect.ref \ functional/policies/check_triggers/C-001/kernel_module_first.expect.lax \ functional/policies/check_triggers/C-001/kernel_module_first.te \ functional/policies/check_triggers/C-001/optional.expect.ref \ functional/policies/check_triggers/C-001/optional.expect.lax \ functional/policies/check_triggers/C-001/optional.te \ functional/policies/check_triggers/C-001/role_ifs.expect.ref \ functional/policies/check_triggers/C-001/role_ifs.expect.lax \ functional/policies/check_triggers/C-001/role_ifs.te \ functional/policies/check_triggers/C-001/simple.expect.ref \ functional/policies/check_triggers/C-001/simple.expect.lax \ functional/policies/check_triggers/C-001/simple.te \ functional/policies/check_triggers/C-001/types_in_requires.expect.ref \ functional/policies/check_triggers/C-001/types_in_requires.expect.lax \ functional/policies/check_triggers/C-001/types_in_requires.te \ functional/policies/check_triggers/C-001/decl_in_block.expect.ref \ functional/policies/check_triggers/C-001/decl_in_block.expect.lax \ functional/policies/check_triggers/C-001/decl_in_block.te \ functional/policies/check_triggers/C-001/interfaces/kernel/domain.if \ functional/policies/check_triggers/C-001/interfaces/kernel/kernel.if \ functional/policies/check_triggers/C-001/interfaces/other/mta.if \ functional/policies/check_triggers/C-001/interfaces/other/role_ifs.if \ functional/policies/check_triggers/C-001/interfaces/system/logging.if \ functional/policies/check_triggers/C-001/interfaces/system/init.if \ functional/policies/context/context.if \ functional/policies/context/context.te \ functional/policies/context2/context2.if \ functional/policies/context2/context2.te \ functional/policies/misc/disable.if \ functional/policies/misc/disable_multiple_other.te \ functional/policies/misc/disable_multiple.te \ functional/policies/misc/disable_require_decl.if \ functional/policies/misc/disable_require_start.te \ functional/policies/misc/disable.te \ functional/policies/misc/fc_macros.fc \ functional/policies/misc/needs_context.te \ functional/policies/misc/nesting.if \ functional/policies/misc/nesting.te \ functional/policies/misc/no_issues.te \ functional/policies/parse_errors/test1.output \ functional/policies/parse_errors/test1.te \ functional/policies/parse_errors/test2.output \ functional/policies/parse_errors/test2.te \ functional/policies/parse_errors/test3.output \ functional/policies/parse_errors/test4.output \ functional/policies/parse_errors/test4.te \ functional/policies/parse_errors/test5.output \ functional/policies/parse_errors/test6.output \ functional/policies/parse_errors/test7.if \ functional/policies/parse_errors/test7.output \ functional/policies/parse_errors/test8.te \ functional/policies/parse_errors/test8.output \ functional/policies/parse_errors/test9.te \ functional/policies/parse_errors/test9.output EXTRA_DIST = ${AV_FILE_PERM_FILES} ${AV_SOCKET_PERM_FILES} ${AV_X_CURSOR_PERM_FILES} ${SAMPLE_CONFIG_FILES} ${SAMPLE_POLICY_FILES} ${FUNCTIONAL_TEST_FILES} TEST_UTILS_HEADS = test_utils.h $(top_builddir)/src/tree.h $(top_builddir)/src/string_list.h # Below does not include test_utils.o, because that will be built by the # inclusion of test_utils.c in SOURCES for each program needing test_utils, # so this only includes the additional object files to link against TEST_UTILS_OBJS = $(top_builddir)/src/tree.o $(top_builddir)/src/string_list.o UTIL_HEADS = $(top_builddir)/src/util.h UTIL_OBJS = $(top_builddir)/src/util.o SELINT_ERROR_HEADS = $(top_builddir)/src/selint_error.h STRING_LIST_HEADS = $(top_builddir)/src/string_list.h ${SELINT_ERROR_HEADS} STRING_LIST_OBJS = $(top_builddir)/src/string_list.o COLOR_HEADS = $(top_builddir)/src/color.h COLOR_OBJS = $(top_builddir)/src/color.o PERM_MACRO_HEADS = $(top_builddir)/src/perm_macro.h ${UTIL_HEADS} ${COLOR_HEADS} PERM_MACRO_OBJS = $(top_builddir)/src/perm_macro.o ${UTIL_OBJS} ${COLOR_OBJS} SELINT_CONFIG_HEADS = $(top_builddir)/src/selint_config.h ${STRING_LIST_HEADS} ${TREE_HEADS} ${MAPS_HEADS} ${ORDERING_HEADS} SELINT_CONFIG_OBJS = $(top_builddir)/src/selint_config.o ${STRING_LIST_OBJS} ${TREE_OBJS} ${MAPS_OBJS} ${UTIL_OBJS} TREE_HEADS = $(top_builddir)/src/tree.h ${STRING_LIST_HEADS} TREE_OBJS = $(top_builddir)/src/tree.o ${STRING_LIST_OBJS} $(top_builddir)/src/maps.o FILE_LIST_HEADS = $(top_builddir)/src/file_list.h ${TREE_HEADS} FILE_LIST_OBJS = $(top_builddir)/src/file_list.o ${TREE_OBJS} MAPS_HEADS = $(top_builddir)/src/maps.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} MAPS_OBJS = $(top_builddir)/src/maps.o ${TREE_OBJS} TEMPLATE_HEADS = $(top_builddir)/src/template.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} TEMPLATE_OBJS = $(top_builddir)/src/template.o ${TREE_OBJS} PARSE_FUNCTIONS_HEADS = $(top_builddir)/src/parse_functions.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} ${MAPS_HEADS} ${PERM_MACRO_HEADS} PARSE_FUNCTIONS_OBJS = $(top_builddir)/src/parse_functions.o ${TEMPLATE_OBJS} ${ORDERING_OBJS} ${PERM_MACRO_OBJS} PARSE_HEADS = $(top_builddir)/src/parse.h ${PARSE_FUNCTIONS_HEADS} PARSE_OBJS = $(top_builddir)/src/parse.o $(top_builddir)/src/lex.o ${CHECK_HOOKS_OBJS} ${PARSE_FUNCTIONS_OBJS} STARTUP_HEADS = $(top_builddir)/src/startup.h ${SELINT_ERROR_HEADS} ${FILE_LIST_HEADS} ${PARSE_HEADS} STARTUP_OBJS = $(top_builddir)/src/startup.o ${FILE_LIST_OBJS} ${PARSE_OBJS} PARSE_FC_HEADS = $(top_builddir)/src/parse_fc.h $(TREE_HEADS) PARSE_FC_OBJS = $(top_builddir)/src/parse_fc.o $(TREE_OBJS) CHECK_HOOKS_HEADS = $(top_builddir)/src/check_hooks.h ${COLOR_HEADS} ${SELINT_ERROR_HEADS} ${TREE_HEADS} CHECK_HOOKS_OBJS = $(top_builddir)/src/check_hooks.o ${COLOR_OBJS} ${TREE_OBJS} FC_CHECKS_HEADS = $(top_builddir)/src/fc_checks.h ${CHECK_HOOKS_HEADS} FC_CHECKS_OBJS = $(top_builddir)/src/fc_checks.o ${CHECK_HOOKS_OBJS} IF_CHECKS_HEADS = $(top_builddir)/src/if_checks.h ${CHECK_HOOKS_HEADS} ${UTIL_HEADS} IF_CHECKS_OBJS = $(top_builddir)/src/if_checks.o ${CHECK_HOOKS_OBJS} ${UTIL_OBJS} TE_CHECKS_HEADS = $(top_builddir)/src/te_checks.h ${CHECK_HOOKS_HEADS} ${UTIL_HEADS} TE_CHECKS_OBJS = $(top_builddir)/src/te_checks.o ${CHECK_HOOKS_OBJS} $(top_builddir)/src/ordering.o ${UTIL_OBJS} RUNNER_HEADS = $(top_builddir)/src/runner.h ${SELINT_ERROR_HEADS} ${CHECK_HOOKS_HEADS} ${PARSE_FUNCTIONS_HEADS} ${FILE_LIST_HEADS} RUNNER_OBJS = $(top_builddir)/src/runner.o ${CHECK_HOOKS_OBJS} ${PARSE_FUNCTIONS_OBJS} ${FILE_LIST_OBJS} ${FC_CHECKS_OBJS} ${IF_CHECKS_OBJS} ${TE_CHECKS_OBJS} ${PARSE_FC_OBJS} ${UTIL_OBJS} ${STARTUP_OBJS} ${PARSE_OBJS} ORDERING_HEADS = $(top_builddir)/src/ordering.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} ORDERING_OBJS = $(top_builddir)/src/ordering.o ${TREE_OBJS} ${MAPS_OBJS} check_string_list_SOURCES = check_string_list.c ${STRING_LIST_HEADS} check_string_list_LDADD = @CHECK_LIBS@ $(sort ${STRING_LIST_OBJS}) check_selint_config_SOURCES = check_selint_config.c ${SELINT_CONFIG_HEADS} ${STRING_LIST_HEADS} check_selint_config_LDADD = @CHECK_LIBS@ $(sort ${SELINT_CONFIG_OBJS} ${STRING_LIST_OBJS}) check_maps_SOURCES = check_maps.c ${MAPS_HEADS} check_maps_LDADD = @CHECK_LIBS@ $(sort ${MAPS_OBJS}) check_startup_SOURCES = check_startup.c ${STARTUP_HEADS} ${MAPS_HEADS} ${SELINT_ERROR_HEADS} check_startup_LDADD = @CHECK_LIBS@ $(sort ${STARTUP_OBJS} ${MAPS_OBJS}) check_tree_SOURCES = check_tree.c test_utils.c ${TREE_HEADS} ${TEST_UTILS_HEADS} check_tree_LDADD = @CHECK_LIBS@ $(sort ${TREE_OBJS} ${MAPS_OBJS} ${TEST_UTILS_OBJS}) check_file_list_SOURCES = check_file_list.c ${FILE_LIST_HEADS} check_file_list_LDADD = @CHECK_LIBS@ $(sort ${FILE_LIST_OBJS}) check_parse_functions_SOURCES = check_parse_functions.c ${PARSE_FUNCTIONS_HEADS} ${MAPS_HEADS} ${PARSE_HEADS} ${SELINT_ERROR_HEADS} check_parse_functions_LDADD = @CHECK_LIBS@ $(sort ${PARSE_FUNCTIONS_OBJS} ${MAPS_OBJS} ${PARSE_OBJS}) check_parsing_SOURCES = check_parsing.c ${PARSE_HEADS} ${TREE_HEADS} ${PARSE_FUNCTIONS_HEADS} ${SELINT_ERROR_HEADS} check_parsing_LDADD = @CHECK_LIBS@ $(sort ${PARSE_OBJS} ${TREE_OBJS} ${PARSE_FUNCTIONS_OBJS}) check_parse_fc_SOURCES = check_parse_fc.c ${PARSE_FC_HEADS} ${TREE_HEADS} check_parse_fc_LDADD = @CHECK_LIBS@ $(sort ${PARSE_FC_OBJS} ${TREE_OBJS}) check_template_SOURCES = check_template.c ${PARSE_FUNCTIONS_HEADS} ${TEMPLATE_HEADS} ${PARSE_HEADS} ${MAPS_HEADS} check_template_LDADD = @CHECK_LIBS@ $(sort ${PARSE_FUNCTIONS_OBJS} ${TEMPLATE_OBJS} ${PARSE_OBJS} ${MAPS_OBJS}) check_check_hooks_SOURCES = check_check_hooks.c ${CHECK_HOOKS_HEADS} check_check_hooks_LDADD = @CHECK_LIBS@ $(sort ${CHECK_HOOKS_OBJS}) check_fc_checks_SOURCES = check_fc_checks.c ${FC_CHECKS_HEADS} ${CHECK_HOOKS_HEADS} ${MAPS_HEADS} check_fc_checks_LDADD = @CHECK_LIBS@ $(sort ${FC_CHECKS_OBJS} ${CHECK_HOOKS_OBJS} ${MAPS_OBJS} ${UTIL_OBJS}) check_if_checks_SOURCES = check_if_checks.c test_utils.c ${IF_CHECKS_HEADS} ${CHECK_HOOKS_HEADS} ${MAPS_HEADS} ${TEST_UTILS_HEADS} check_if_checks_LDADD = @CHECK_LIBS@ $(sort ${IF_CHECKS_OBJS} ${CHECK_HOOKS_OBJS} ${MAPS_OBJS} ${TEST_UTILS_OBJS}) check_te_checks_SOURCES = check_te_checks.c test_utils.c ${TE_CHECKS_HEADS} ${CHECK_HOOKS_HEADS} ${MAPS_HEADS} ${TEST_UTILS_HEADS} ${PERM_MACRO_HEADS} check_te_checks_LDADD = @CHECK_LIBS@ $(sort ${TE_CHECKS_OBJS} ${CHECK_HOOKS_OBJS} ${MAPS_OBJS} ${TEST_UTILS_OBJS} ${PERM_MACRO_OBJS}) check_runner_SOURCES = check_runner.c ${STRING_LIST_HEADS} ${RUNNER_HEADS} check_runner_LDADD = @CHECK_LIBS@ $(sort ${STRING_LIST_OBJS} ${RUNNER_OBJS}) check_ordering_SOURCES = check_ordering.c ${ORDERING_HEADS} ${RUNNER_HEADS} ${MAPS_HEADS} check_ordering_LDADD = @CHECK_LIBS@ $(sort ${ORDERING_OBJS} ${RUNNER_OBJS} ${MAPS_OBJS}) check_perm_macro_SOURCES = check_perm_macro.c ${PERM_MACRO_HEADS} ${STARTUP_HEADS} ${SELINT_ERROR_HEADS} ${MAPS_HEADS} check_perm_macro_LDADD = @CHECK_LIBS@ $(sort ${PERM_MACRO_OBJS} ${STARTUP_OBJS} ${MAPS_OBJS}) MOSTLYCLEANFILES = *.gcov *.gcda *.gcno all: all-am .SUFFIXES: .SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) check_check_hooks$(EXEEXT): $(check_check_hooks_OBJECTS) $(check_check_hooks_DEPENDENCIES) $(EXTRA_check_check_hooks_DEPENDENCIES) @rm -f check_check_hooks$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_check_hooks_OBJECTS) $(check_check_hooks_LDADD) $(LIBS) check_fc_checks$(EXEEXT): $(check_fc_checks_OBJECTS) $(check_fc_checks_DEPENDENCIES) $(EXTRA_check_fc_checks_DEPENDENCIES) @rm -f check_fc_checks$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_fc_checks_OBJECTS) $(check_fc_checks_LDADD) $(LIBS) check_file_list$(EXEEXT): $(check_file_list_OBJECTS) $(check_file_list_DEPENDENCIES) $(EXTRA_check_file_list_DEPENDENCIES) @rm -f check_file_list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_file_list_OBJECTS) $(check_file_list_LDADD) $(LIBS) check_if_checks$(EXEEXT): $(check_if_checks_OBJECTS) $(check_if_checks_DEPENDENCIES) $(EXTRA_check_if_checks_DEPENDENCIES) @rm -f check_if_checks$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_if_checks_OBJECTS) $(check_if_checks_LDADD) $(LIBS) check_maps$(EXEEXT): $(check_maps_OBJECTS) $(check_maps_DEPENDENCIES) $(EXTRA_check_maps_DEPENDENCIES) @rm -f check_maps$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_maps_OBJECTS) $(check_maps_LDADD) $(LIBS) check_ordering$(EXEEXT): $(check_ordering_OBJECTS) $(check_ordering_DEPENDENCIES) $(EXTRA_check_ordering_DEPENDENCIES) @rm -f check_ordering$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_ordering_OBJECTS) $(check_ordering_LDADD) $(LIBS) check_parse_fc$(EXEEXT): $(check_parse_fc_OBJECTS) $(check_parse_fc_DEPENDENCIES) $(EXTRA_check_parse_fc_DEPENDENCIES) @rm -f check_parse_fc$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_parse_fc_OBJECTS) $(check_parse_fc_LDADD) $(LIBS) check_parse_functions$(EXEEXT): $(check_parse_functions_OBJECTS) $(check_parse_functions_DEPENDENCIES) $(EXTRA_check_parse_functions_DEPENDENCIES) @rm -f check_parse_functions$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_parse_functions_OBJECTS) $(check_parse_functions_LDADD) $(LIBS) check_parsing$(EXEEXT): $(check_parsing_OBJECTS) $(check_parsing_DEPENDENCIES) $(EXTRA_check_parsing_DEPENDENCIES) @rm -f check_parsing$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_parsing_OBJECTS) $(check_parsing_LDADD) $(LIBS) check_perm_macro$(EXEEXT): $(check_perm_macro_OBJECTS) $(check_perm_macro_DEPENDENCIES) $(EXTRA_check_perm_macro_DEPENDENCIES) @rm -f check_perm_macro$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_perm_macro_OBJECTS) $(check_perm_macro_LDADD) $(LIBS) check_runner$(EXEEXT): $(check_runner_OBJECTS) $(check_runner_DEPENDENCIES) $(EXTRA_check_runner_DEPENDENCIES) @rm -f check_runner$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_runner_OBJECTS) $(check_runner_LDADD) $(LIBS) check_selint_config$(EXEEXT): $(check_selint_config_OBJECTS) $(check_selint_config_DEPENDENCIES) $(EXTRA_check_selint_config_DEPENDENCIES) @rm -f check_selint_config$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_selint_config_OBJECTS) $(check_selint_config_LDADD) $(LIBS) check_startup$(EXEEXT): $(check_startup_OBJECTS) $(check_startup_DEPENDENCIES) $(EXTRA_check_startup_DEPENDENCIES) @rm -f check_startup$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_startup_OBJECTS) $(check_startup_LDADD) $(LIBS) check_string_list$(EXEEXT): $(check_string_list_OBJECTS) $(check_string_list_DEPENDENCIES) $(EXTRA_check_string_list_DEPENDENCIES) @rm -f check_string_list$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_string_list_OBJECTS) $(check_string_list_LDADD) $(LIBS) check_te_checks$(EXEEXT): $(check_te_checks_OBJECTS) $(check_te_checks_DEPENDENCIES) $(EXTRA_check_te_checks_DEPENDENCIES) @rm -f check_te_checks$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_te_checks_OBJECTS) $(check_te_checks_LDADD) $(LIBS) check_template$(EXEEXT): $(check_template_OBJECTS) $(check_template_DEPENDENCIES) $(EXTRA_check_template_DEPENDENCIES) @rm -f check_template$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_template_OBJECTS) $(check_template_LDADD) $(LIBS) check_tree$(EXEEXT): $(check_tree_OBJECTS) $(check_tree_DEPENDENCIES) $(EXTRA_check_tree_DEPENDENCIES) @rm -f check_tree$(EXEEXT) $(AM_V_CCLD)$(LINK) $(check_tree_OBJECTS) $(check_tree_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_check_hooks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_fc_checks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_file_list.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_if_checks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_maps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_ordering.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_parse_fc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_parse_functions.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_parsing.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_perm_macro.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_runner.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_selint_config.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_startup.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_string_list.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_te_checks.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_template.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_tree.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_utils.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? check_tree.log: check_tree$(EXEEXT) @p='check_tree$(EXEEXT)'; \ b='check_tree'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_parse_functions.log: check_parse_functions$(EXEEXT) @p='check_parse_functions$(EXEEXT)'; \ b='check_parse_functions'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_maps.log: check_maps$(EXEEXT) @p='check_maps$(EXEEXT)'; \ b='check_maps'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_parsing.log: check_parsing$(EXEEXT) @p='check_parsing$(EXEEXT)'; \ b='check_parsing'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_parse_fc.log: check_parse_fc$(EXEEXT) @p='check_parse_fc$(EXEEXT)'; \ b='check_parse_fc'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_template.log: check_template$(EXEEXT) @p='check_template$(EXEEXT)'; \ b='check_template'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_file_list.log: check_file_list$(EXEEXT) @p='check_file_list$(EXEEXT)'; \ b='check_file_list'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_fc_checks.log: check_fc_checks$(EXEEXT) @p='check_fc_checks$(EXEEXT)'; \ b='check_fc_checks'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_check_hooks.log: check_check_hooks$(EXEEXT) @p='check_check_hooks$(EXEEXT)'; \ b='check_check_hooks'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_selint_config.log: check_selint_config$(EXEEXT) @p='check_selint_config$(EXEEXT)'; \ b='check_selint_config'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_if_checks.log: check_if_checks$(EXEEXT) @p='check_if_checks$(EXEEXT)'; \ b='check_if_checks'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_string_list.log: check_string_list$(EXEEXT) @p='check_string_list$(EXEEXT)'; \ b='check_string_list'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_runner.log: check_runner$(EXEEXT) @p='check_runner$(EXEEXT)'; \ b='check_runner'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_startup.log: check_startup$(EXEEXT) @p='check_startup$(EXEEXT)'; \ b='check_startup'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_te_checks.log: check_te_checks$(EXEEXT) @p='check_te_checks$(EXEEXT)'; \ b='check_te_checks'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_ordering.log: check_ordering$(EXEEXT) @p='check_ordering$(EXEEXT)'; \ b='check_ordering'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_perm_macro.log: check_perm_macro$(EXEEXT) @p='check_perm_macro$(EXEEXT)'; \ b='check_perm_macro'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/check_check_hooks.Po -rm -f ./$(DEPDIR)/check_fc_checks.Po -rm -f ./$(DEPDIR)/check_file_list.Po -rm -f ./$(DEPDIR)/check_if_checks.Po -rm -f ./$(DEPDIR)/check_maps.Po -rm -f ./$(DEPDIR)/check_ordering.Po -rm -f ./$(DEPDIR)/check_parse_fc.Po -rm -f ./$(DEPDIR)/check_parse_functions.Po -rm -f ./$(DEPDIR)/check_parsing.Po -rm -f ./$(DEPDIR)/check_perm_macro.Po -rm -f ./$(DEPDIR)/check_runner.Po -rm -f ./$(DEPDIR)/check_selint_config.Po -rm -f ./$(DEPDIR)/check_startup.Po -rm -f ./$(DEPDIR)/check_string_list.Po -rm -f ./$(DEPDIR)/check_te_checks.Po -rm -f ./$(DEPDIR)/check_template.Po -rm -f ./$(DEPDIR)/check_tree.Po -rm -f ./$(DEPDIR)/test_utils.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/check_check_hooks.Po -rm -f ./$(DEPDIR)/check_fc_checks.Po -rm -f ./$(DEPDIR)/check_file_list.Po -rm -f ./$(DEPDIR)/check_if_checks.Po -rm -f ./$(DEPDIR)/check_maps.Po -rm -f ./$(DEPDIR)/check_ordering.Po -rm -f ./$(DEPDIR)/check_parse_fc.Po -rm -f ./$(DEPDIR)/check_parse_functions.Po -rm -f ./$(DEPDIR)/check_parsing.Po -rm -f ./$(DEPDIR)/check_perm_macro.Po -rm -f ./$(DEPDIR)/check_runner.Po -rm -f ./$(DEPDIR)/check_selint_config.Po -rm -f ./$(DEPDIR)/check_startup.Po -rm -f ./$(DEPDIR)/check_string_list.Po -rm -f ./$(DEPDIR)/check_te_checks.Po -rm -f ./$(DEPDIR)/check_template.Po -rm -f ./$(DEPDIR)/check_tree.Po -rm -f ./$(DEPDIR)/test_utils.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile @VALGRIND_CHECK_RULES@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: selint-1.2.1/tests/Makefile.am0000644000175100001710000004357114167117255013150 00000000000000# Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. @VALGRIND_CHECK_RULES@ VALGRIND_memcheck_FLAGS=--leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all TESTS = check_tree check_parse_functions check_maps check_parsing check_parse_fc check_template check_file_list check_fc_checks check_check_hooks check_selint_config check_if_checks check_string_list check_runner check_startup check_te_checks check_ordering check_perm_macro check_PROGRAMS = ${TESTS} AV_FILE_PERM_FILES=sample_av/file/index \ sample_av/file/perms/append \ sample_av/file/perms/audit_access \ sample_av/file/perms/create \ sample_av/file/perms/entrypoint \ sample_av/file/perms/execmod \ sample_av/file/perms/execute \ sample_av/file/perms/execute_no_trans \ sample_av/file/perms/getattr \ sample_av/file/perms/ioctl \ sample_av/file/perms/link \ sample_av/file/perms/lock \ sample_av/file/perms/map \ sample_av/file/perms/mounton \ sample_av/file/perms/open \ sample_av/file/perms/quotaon \ sample_av/file/perms/read \ sample_av/file/perms/relabelfrom \ sample_av/file/perms/relabelto \ sample_av/file/perms/rename \ sample_av/file/perms/setattr \ sample_av/file/perms/swapon \ sample_av/file/perms/unlink \ sample_av/file/perms/write AV_SOCKET_PERM_FILES=sample_av/socket/index \ sample_av/socket/perms/accept \ sample_av/socket/perms/append \ sample_av/socket/perms/bind \ sample_av/socket/perms/connect \ sample_av/socket/perms/create \ sample_av/socket/perms/getattr \ sample_av/socket/perms/getopt \ sample_av/socket/perms/ioctl \ sample_av/socket/perms/listen \ sample_av/socket/perms/lock \ sample_av/socket/perms/map \ sample_av/socket/perms/name_bind \ sample_av/socket/perms/read \ sample_av/socket/perms/recvfrom \ sample_av/socket/perms/recv_msg \ sample_av/socket/perms/relabelfrom \ sample_av/socket/perms/relabelto \ sample_av/socket/perms/send_msg \ sample_av/socket/perms/sendto \ sample_av/socket/perms/setattr \ sample_av/socket/perms/setopt \ sample_av/socket/perms/shutdown \ sample_av/socket/perms/write AV_X_CURSOR_PERM_FILES=sample_av/x_cursor/index \ sample_av/x_cursor/perms/create \ sample_av/x_cursor/perms/destroy \ sample_av/x_cursor/perms/getattr \ sample_av/x_cursor/perms/read \ sample_av/x_cursor/perms/setattr \ sample_av/x_cursor/perms/use \ sample_av/x_cursor/perms/write SAMPLE_CONFIG_FILES=sample_configs/bad_format_2.conf \ sample_configs/bad_format.conf \ sample_configs/check_config.conf \ sample_configs/invalid_option.conf \ sample_configs/severity_convention.conf \ sample_configs/severity_error.conf \ sample_configs/severity_fatal.conf \ sample_configs/severity_invalid.conf \ sample_configs/severity_style.conf \ sample_configs/severity_warning.conf \ sample_configs/bad_order.conf \ sample_configs/refpolicy_ordering.conf \ sample_configs/order_requires.conf SAMPLE_POLICY_FILES=sample_policy_files/access_vectors \ sample_policy_files/bad_modules.conf \ sample_policy_files/bad_obj_perm_sets.spt \ sample_policy_files/bad_role_allow.te \ sample_policy_files/basic.fc \ sample_policy_files/basic.if \ sample_policy_files/basic.te \ sample_policy_files/blocks.te \ sample_policy_files/bool_declarations.te \ sample_policy_files/declaring_template.if \ sample_policy_files/declaring_template.te \ sample_policy_files/disable_comment.if \ sample_policy_files/disable_comment.te \ sample_policy_files/empty.te \ sample_policy_files/extended_perms.te \ sample_policy_files/ifdef_block.te \ sample_policy_files/modules.conf \ sample_policy_files/nested_templates.if \ sample_policy_files/none_context.fc \ sample_policy_files/obj_perm_sets.spt \ sample_policy_files/perms.spt \ sample_policy_files/syntax_error.te \ sample_policy_files/uncommon.te \ sample_policy_files/with_m4.fc FUNCTIONAL_TEST_FILES=functional/end-to-end.bats \ functional/configs/bad_ids.conf \ functional/configs/broken.conf \ functional/configs/default.conf \ functional/configs/empty.conf \ functional/configs/fc_macros.conf \ functional/configs/order_ref.conf \ functional/configs/order_lax.conf \ functional/policies/check_triggers/access_vectors \ functional/policies/check_triggers/c04.if \ functional/policies/check_triggers/c05.if \ functional/policies/check_triggers/c05.te \ functional/policies/check_triggers/c06.pass.if \ functional/policies/check_triggers/c06.warn.if \ functional/policies/check_triggers/c07.te \ functional/policies/check_triggers/c07.if \ functional/policies/check_triggers/e02.fc \ functional/policies/check_triggers/e03e04e05.fc \ functional/policies/check_triggers/e06.te \ functional/policies/check_triggers/e06.if \ functional/policies/check_triggers/e07.pass.te \ functional/policies/check_triggers/e07.warn.te \ functional/policies/check_triggers/e08.pass.te \ functional/policies/check_triggers/e08.warn.te \ functional/policies/check_triggers/e09.te \ functional/policies/check_triggers/e10.pass.te \ functional/policies/check_triggers/e10.warn.te \ functional/policies/check_triggers/modules.conf \ functional/policies/check_triggers/obj_perm_sets.spt \ functional/policies/check_triggers/s01.te \ functional/policies/check_triggers/s02.fc \ functional/policies/check_triggers/s02_other.te \ functional/policies/check_triggers/s03.te \ functional/policies/check_triggers/s04.if \ functional/policies/check_triggers/s05.if \ functional/policies/check_triggers/s06.te \ functional/policies/check_triggers/s07.fc \ functional/policies/check_triggers/s08.if \ functional/policies/check_triggers/s09.pass.te \ functional/policies/check_triggers/s09.warn.te \ functional/policies/check_triggers/w01_other.te \ functional/policies/check_triggers/w01.te \ functional/policies/check_triggers/w02.if \ functional/policies/check_triggers/w02_role.if \ functional/policies/check_triggers/w02_role.te \ functional/policies/check_triggers/w02.te \ functional/policies/check_triggers/w03_alias.if \ functional/policies/check_triggers/w03.if \ functional/policies/check_triggers/w03_role.if \ functional/policies/check_triggers/w03_stub.if \ functional/policies/check_triggers/w03_ta.if \ functional/policies/check_triggers/w04.fc \ functional/policies/check_triggers/w05_other.if \ functional/policies/check_triggers/w05.te \ functional/policies/check_triggers/w06.if \ functional/policies/check_triggers/w07.if \ functional/policies/check_triggers/w07.0.te \ functional/policies/check_triggers/w07.1.te \ functional/policies/check_triggers/w08.1.te \ functional/policies/check_triggers/w08.2.te \ functional/policies/check_triggers/w09.te \ functional/policies/check_triggers/w10.pass.te \ functional/policies/check_triggers/w10.warn.te \ functional/policies/check_triggers/w11.te \ functional/policies/check_triggers/w11.if \ functional/policies/check_triggers/C-001/interleaved.expect.ref \ functional/policies/check_triggers/C-001/interleaved.expect.lax \ functional/policies/check_triggers/C-001/interleaved.te \ functional/policies/check_triggers/C-001/if_in_optional.expect.ref \ functional/policies/check_triggers/C-001/if_in_optional.expect.lax \ functional/policies/check_triggers/C-001/if_in_optional.te \ functional/policies/check_triggers/C-001/kernel_module_first.expect.ref \ functional/policies/check_triggers/C-001/kernel_module_first.expect.lax \ functional/policies/check_triggers/C-001/kernel_module_first.te \ functional/policies/check_triggers/C-001/optional.expect.ref \ functional/policies/check_triggers/C-001/optional.expect.lax \ functional/policies/check_triggers/C-001/optional.te \ functional/policies/check_triggers/C-001/role_ifs.expect.ref \ functional/policies/check_triggers/C-001/role_ifs.expect.lax \ functional/policies/check_triggers/C-001/role_ifs.te \ functional/policies/check_triggers/C-001/simple.expect.ref \ functional/policies/check_triggers/C-001/simple.expect.lax \ functional/policies/check_triggers/C-001/simple.te \ functional/policies/check_triggers/C-001/types_in_requires.expect.ref \ functional/policies/check_triggers/C-001/types_in_requires.expect.lax \ functional/policies/check_triggers/C-001/types_in_requires.te \ functional/policies/check_triggers/C-001/decl_in_block.expect.ref \ functional/policies/check_triggers/C-001/decl_in_block.expect.lax \ functional/policies/check_triggers/C-001/decl_in_block.te \ functional/policies/check_triggers/C-001/interfaces/kernel/domain.if \ functional/policies/check_triggers/C-001/interfaces/kernel/kernel.if \ functional/policies/check_triggers/C-001/interfaces/other/mta.if \ functional/policies/check_triggers/C-001/interfaces/other/role_ifs.if \ functional/policies/check_triggers/C-001/interfaces/system/logging.if \ functional/policies/check_triggers/C-001/interfaces/system/init.if \ functional/policies/context/context.if \ functional/policies/context/context.te \ functional/policies/context2/context2.if \ functional/policies/context2/context2.te \ functional/policies/misc/disable.if \ functional/policies/misc/disable_multiple_other.te \ functional/policies/misc/disable_multiple.te \ functional/policies/misc/disable_require_decl.if \ functional/policies/misc/disable_require_start.te \ functional/policies/misc/disable.te \ functional/policies/misc/fc_macros.fc \ functional/policies/misc/needs_context.te \ functional/policies/misc/nesting.if \ functional/policies/misc/nesting.te \ functional/policies/misc/no_issues.te \ functional/policies/parse_errors/test1.output \ functional/policies/parse_errors/test1.te \ functional/policies/parse_errors/test2.output \ functional/policies/parse_errors/test2.te \ functional/policies/parse_errors/test3.output \ functional/policies/parse_errors/test4.output \ functional/policies/parse_errors/test4.te \ functional/policies/parse_errors/test5.output \ functional/policies/parse_errors/test6.output \ functional/policies/parse_errors/test7.if \ functional/policies/parse_errors/test7.output \ functional/policies/parse_errors/test8.te \ functional/policies/parse_errors/test8.output \ functional/policies/parse_errors/test9.te \ functional/policies/parse_errors/test9.output EXTRA_DIST = ${AV_FILE_PERM_FILES} ${AV_SOCKET_PERM_FILES} ${AV_X_CURSOR_PERM_FILES} ${SAMPLE_CONFIG_FILES} ${SAMPLE_POLICY_FILES} ${FUNCTIONAL_TEST_FILES} AM_CFLAGS += @CHECK_CFLAGS@ -DSAMPLE_POL_DIR="\"$(srcdir)/sample_policy_files/\"" -DSAMPLE_CONF_DIR="\"$(srcdir)/sample_configs/\"" -DSAMPLE_AV_DIR="\"$(srcdir)/sample_av/\"" if COND_GCOV AM_CFLAGS += --coverage -fno-inline -fno-inline-small-functions -fno-default-inline endif TEST_UTILS_HEADS=test_utils.h $(top_builddir)/src/tree.h $(top_builddir)/src/string_list.h # Below does not include test_utils.o, because that will be built by the # inclusion of test_utils.c in SOURCES for each program needing test_utils, # so this only includes the additional object files to link against TEST_UTILS_OBJS=$(top_builddir)/src/tree.o $(top_builddir)/src/string_list.o UTIL_HEADS=$(top_builddir)/src/util.h UTIL_OBJS=$(top_builddir)/src/util.o SELINT_ERROR_HEADS=$(top_builddir)/src/selint_error.h STRING_LIST_HEADS=$(top_builddir)/src/string_list.h ${SELINT_ERROR_HEADS} STRING_LIST_OBJS=$(top_builddir)/src/string_list.o COLOR_HEADS=$(top_builddir)/src/color.h COLOR_OBJS=$(top_builddir)/src/color.o PERM_MACRO_HEADS=$(top_builddir)/src/perm_macro.h ${UTIL_HEADS} ${COLOR_HEADS} PERM_MACRO_OBJS=$(top_builddir)/src/perm_macro.o ${UTIL_OBJS} ${COLOR_OBJS} SELINT_CONFIG_HEADS=$(top_builddir)/src/selint_config.h ${STRING_LIST_HEADS} ${TREE_HEADS} ${MAPS_HEADS} ${ORDERING_HEADS} SELINT_CONFIG_OBJS=$(top_builddir)/src/selint_config.o ${STRING_LIST_OBJS} ${TREE_OBJS} ${MAPS_OBJS} ${UTIL_OBJS} TREE_HEADS=$(top_builddir)/src/tree.h ${STRING_LIST_HEADS} TREE_OBJS=$(top_builddir)/src/tree.o ${STRING_LIST_OBJS} $(top_builddir)/src/maps.o FILE_LIST_HEADS=$(top_builddir)/src/file_list.h ${TREE_HEADS} FILE_LIST_OBJS=$(top_builddir)/src/file_list.o ${TREE_OBJS} MAPS_HEADS=$(top_builddir)/src/maps.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} MAPS_OBJS=$(top_builddir)/src/maps.o ${TREE_OBJS} TEMPLATE_HEADS=$(top_builddir)/src/template.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} TEMPLATE_OBJS=$(top_builddir)/src/template.o ${TREE_OBJS} PARSE_FUNCTIONS_HEADS=$(top_builddir)/src/parse_functions.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} ${MAPS_HEADS} ${PERM_MACRO_HEADS} PARSE_FUNCTIONS_OBJS=$(top_builddir)/src/parse_functions.o ${TEMPLATE_OBJS} ${ORDERING_OBJS} ${PERM_MACRO_OBJS} PARSE_HEADS=$(top_builddir)/src/parse.h ${PARSE_FUNCTIONS_HEADS} PARSE_OBJS=$(top_builddir)/src/parse.o $(top_builddir)/src/lex.o ${CHECK_HOOKS_OBJS} ${PARSE_FUNCTIONS_OBJS} STARTUP_HEADS=$(top_builddir)/src/startup.h ${SELINT_ERROR_HEADS} ${FILE_LIST_HEADS} ${PARSE_HEADS} STARTUP_OBJS=$(top_builddir)/src/startup.o ${FILE_LIST_OBJS} ${PARSE_OBJS} PARSE_FC_HEADS = $(top_builddir)/src/parse_fc.h $(TREE_HEADS) PARSE_FC_OBJS = $(top_builddir)/src/parse_fc.o $(TREE_OBJS) CHECK_HOOKS_HEADS=$(top_builddir)/src/check_hooks.h ${COLOR_HEADS} ${SELINT_ERROR_HEADS} ${TREE_HEADS} CHECK_HOOKS_OBJS=$(top_builddir)/src/check_hooks.o ${COLOR_OBJS} ${TREE_OBJS} FC_CHECKS_HEADS=$(top_builddir)/src/fc_checks.h ${CHECK_HOOKS_HEADS} FC_CHECKS_OBJS=$(top_builddir)/src/fc_checks.o ${CHECK_HOOKS_OBJS} IF_CHECKS_HEADS=$(top_builddir)/src/if_checks.h ${CHECK_HOOKS_HEADS} ${UTIL_HEADS} IF_CHECKS_OBJS=$(top_builddir)/src/if_checks.o ${CHECK_HOOKS_OBJS} ${UTIL_OBJS} TE_CHECKS_HEADS=$(top_builddir)/src/te_checks.h ${CHECK_HOOKS_HEADS} ${UTIL_HEADS} TE_CHECKS_OBJS=$(top_builddir)/src/te_checks.o ${CHECK_HOOKS_OBJS} $(top_builddir)/src/ordering.o ${UTIL_OBJS} RUNNER_HEADS=$(top_builddir)/src/runner.h ${SELINT_ERROR_HEADS} ${CHECK_HOOKS_HEADS} ${PARSE_FUNCTIONS_HEADS} ${FILE_LIST_HEADS} RUNNER_OBJS=$(top_builddir)/src/runner.o ${CHECK_HOOKS_OBJS} ${PARSE_FUNCTIONS_OBJS} ${FILE_LIST_OBJS} ${FC_CHECKS_OBJS} ${IF_CHECKS_OBJS} ${TE_CHECKS_OBJS} ${PARSE_FC_OBJS} ${UTIL_OBJS} ${STARTUP_OBJS} ${PARSE_OBJS} ORDERING_HEADS=$(top_builddir)/src/ordering.h ${SELINT_ERROR_HEADS} ${TREE_HEADS} ORDERING_OBJS=$(top_builddir)/src/ordering.o ${TREE_OBJS} ${MAPS_OBJS} check_string_list_SOURCES = check_string_list.c ${STRING_LIST_HEADS} check_string_list_LDADD = @CHECK_LIBS@ $(sort ${STRING_LIST_OBJS}) check_selint_config_SOURCES = check_selint_config.c ${SELINT_CONFIG_HEADS} ${STRING_LIST_HEADS} check_selint_config_LDADD = @CHECK_LIBS@ $(sort ${SELINT_CONFIG_OBJS} ${STRING_LIST_OBJS}) check_maps_SOURCES = check_maps.c ${MAPS_HEADS} check_maps_LDADD = @CHECK_LIBS@ $(sort ${MAPS_OBJS}) check_startup_SOURCES = check_startup.c ${STARTUP_HEADS} ${MAPS_HEADS} ${SELINT_ERROR_HEADS} check_startup_LDADD = @CHECK_LIBS@ $(sort ${STARTUP_OBJS} ${MAPS_OBJS}) check_tree_SOURCES = check_tree.c test_utils.c ${TREE_HEADS} ${TEST_UTILS_HEADS} check_tree_LDADD = @CHECK_LIBS@ $(sort ${TREE_OBJS} ${MAPS_OBJS} ${TEST_UTILS_OBJS}) check_file_list_SOURCES = check_file_list.c ${FILE_LIST_HEADS} check_file_list_LDADD = @CHECK_LIBS@ $(sort ${FILE_LIST_OBJS}) check_parse_functions_SOURCES = check_parse_functions.c ${PARSE_FUNCTIONS_HEADS} ${MAPS_HEADS} ${PARSE_HEADS} ${SELINT_ERROR_HEADS} check_parse_functions_LDADD = @CHECK_LIBS@ $(sort ${PARSE_FUNCTIONS_OBJS} ${MAPS_OBJS} ${PARSE_OBJS}) check_parsing_SOURCES = check_parsing.c ${PARSE_HEADS} ${TREE_HEADS} ${PARSE_FUNCTIONS_HEADS} ${SELINT_ERROR_HEADS} check_parsing_LDADD = @CHECK_LIBS@ $(sort ${PARSE_OBJS} ${TREE_OBJS} ${PARSE_FUNCTIONS_OBJS}) check_parse_fc_SOURCES = check_parse_fc.c ${PARSE_FC_HEADS} ${TREE_HEADS} check_parse_fc_LDADD = @CHECK_LIBS@ $(sort ${PARSE_FC_OBJS} ${TREE_OBJS}) check_template_SOURCES = check_template.c ${PARSE_FUNCTIONS_HEADS} ${TEMPLATE_HEADS} ${PARSE_HEADS} ${MAPS_HEADS} check_template_LDADD = @CHECK_LIBS@ $(sort ${PARSE_FUNCTIONS_OBJS} ${TEMPLATE_OBJS} ${PARSE_OBJS} ${MAPS_OBJS}) check_check_hooks_SOURCES = check_check_hooks.c ${CHECK_HOOKS_HEADS} check_check_hooks_LDADD = @CHECK_LIBS@ $(sort ${CHECK_HOOKS_OBJS}) check_fc_checks_SOURCES = check_fc_checks.c ${FC_CHECKS_HEADS} ${CHECK_HOOKS_HEADS} ${MAPS_HEADS} check_fc_checks_LDADD = @CHECK_LIBS@ $(sort ${FC_CHECKS_OBJS} ${CHECK_HOOKS_OBJS} ${MAPS_OBJS} ${UTIL_OBJS}) check_if_checks_SOURCES = check_if_checks.c test_utils.c ${IF_CHECKS_HEADS} ${CHECK_HOOKS_HEADS} ${MAPS_HEADS} ${TEST_UTILS_HEADS} check_if_checks_LDADD = @CHECK_LIBS@ $(sort ${IF_CHECKS_OBJS} ${CHECK_HOOKS_OBJS} ${MAPS_OBJS} ${TEST_UTILS_OBJS}) check_te_checks_SOURCES = check_te_checks.c test_utils.c ${TE_CHECKS_HEADS} ${CHECK_HOOKS_HEADS} ${MAPS_HEADS} ${TEST_UTILS_HEADS} ${PERM_MACRO_HEADS} check_te_checks_LDADD = @CHECK_LIBS@ $(sort ${TE_CHECKS_OBJS} ${CHECK_HOOKS_OBJS} ${MAPS_OBJS} ${TEST_UTILS_OBJS} ${PERM_MACRO_OBJS}) check_runner_SOURCES = check_runner.c ${STRING_LIST_HEADS} ${RUNNER_HEADS} check_runner_LDADD = @CHECK_LIBS@ $(sort ${STRING_LIST_OBJS} ${RUNNER_OBJS}) check_ordering_SOURCES = check_ordering.c ${ORDERING_HEADS} ${RUNNER_HEADS} ${MAPS_HEADS} check_ordering_LDADD = @CHECK_LIBS@ $(sort ${ORDERING_OBJS} ${RUNNER_OBJS} ${MAPS_OBJS}) check_perm_macro_SOURCES = check_perm_macro.c ${PERM_MACRO_HEADS} ${STARTUP_HEADS} ${SELINT_ERROR_HEADS} ${MAPS_HEADS} check_perm_macro_LDADD = @CHECK_LIBS@ $(sort ${PERM_MACRO_OBJS} ${STARTUP_OBJS} ${MAPS_OBJS}) MOSTLYCLEANFILES = *.gcov *.gcda *.gcno selint-1.2.1/tests/check_fc_checks.c0000644000175100001710000002354614167117255014325 00000000000000/* * Copyright 2019 Tresys Technology, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "../src/fc_checks.h" #include "../src/check_hooks.h" #include "../src/maps.h" START_TEST (test_check_file_context_types_exist) { struct check_data *data = malloc(sizeof(struct check_data)); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_FC_ENTRY; struct fc_entry *entry = malloc(sizeof(struct fc_entry)); memset(entry, 0, sizeof(struct fc_entry)); entry->context = malloc(sizeof(struct sel_context)); memset(entry->context, 0, sizeof(struct sel_context)); entry->context->type = strdup("foo_t"); node->data.fc_data = entry; struct check_result *res = check_file_context_types_exist(data, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'E'); ck_assert_int_eq(res->check_id, E_ID_FC_TYPE); ck_assert_ptr_nonnull(res->message); free_check_result(res); insert_into_decl_map("foo_t", "foo", DECL_TYPE); res = check_file_context_types_exist(data, node); ck_assert_ptr_null(res); free_all_maps(); free(data->mod_name); free(data); free_policy_node(node); } END_TEST START_TEST (test_check_file_context_types_exist_bad_flavor) { struct check_data *data = malloc(sizeof(struct check_data)); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_TE_FILE; struct check_result *res = check_file_context_types_exist(data, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq('F', res->severity); ck_assert_int_eq(F_ID_INTERNAL, res->check_id); ck_assert_ptr_nonnull(res->message); free_check_result(res); free(data->mod_name); free(data); free_policy_node(node); } END_TEST START_TEST (test_check_file_context_types_in_mod) { struct check_data *data = malloc(sizeof(struct check_data)); data->filename = strdup("foo"); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; const struct config_check_data cfg = { ORDER_LAX, {}, true, true, NULL }; data->config_check_data = &cfg; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_FC_ENTRY; struct fc_entry *entry = malloc(sizeof(struct fc_entry)); memset(entry, 0, sizeof(struct fc_entry)); entry->context = malloc(sizeof(struct sel_context)); memset(entry->context, 0, sizeof(struct sel_context)); entry->context->type = strdup("foo_t"); node->data.fc_data = entry; struct check_result *res = check_file_context_types_in_mod(data, node); ck_assert_ptr_null(res); insert_into_decl_map("foo_t", "bar", DECL_TYPE); res = check_file_context_types_in_mod(data, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'S'); ck_assert_int_eq(res->check_id, S_ID_FC_TYPE); ck_assert_ptr_nonnull(res->message); free_check_result(res); free(data->mod_name); data->mod_name = strdup("bar"); res = check_file_context_types_exist(data, node); ck_assert_ptr_null(res); free(res); free_all_maps(); free(data->mod_name); free(data->filename); free(data); free_policy_node(node); } END_TEST START_TEST (test_check_file_context_roles) { struct check_data *data = malloc(sizeof(struct check_data)); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_FC_ENTRY; struct fc_entry *entry = malloc(sizeof(struct fc_entry)); memset(entry, 0, sizeof(struct fc_entry)); entry->context = malloc(sizeof(struct sel_context)); memset(entry->context, 0, sizeof(struct sel_context)); entry->context->role = strdup("object_r"); node->data.fc_data = entry; struct check_result *res = check_file_context_roles(data, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'E'); ck_assert_int_eq(res->check_id, E_ID_FC_ROLE); ck_assert_ptr_nonnull(res->message); free_check_result(res); insert_into_decl_map("object_r", "files", DECL_ROLE); res = check_file_context_roles(data, node); ck_assert_ptr_null(res); free(res); free_all_maps(); free(data->mod_name); free(data); free_policy_node(node); } END_TEST START_TEST (test_check_file_context_users) { struct check_data *data = malloc(sizeof(struct check_data)); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_FC_ENTRY; struct fc_entry *entry = malloc(sizeof(struct fc_entry)); memset(entry, 0, sizeof(struct fc_entry)); entry->context = malloc(sizeof(struct sel_context)); memset(entry->context, 0, sizeof(struct sel_context)); entry->context->user = strdup("system_u"); node->data.fc_data = entry; struct check_result *res = check_file_context_users(data, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'E'); ck_assert_int_eq(res->check_id, E_ID_FC_USER); ck_assert_ptr_nonnull(res->message); free_check_result(res); insert_into_decl_map("system_u", "files", DECL_USER); res = check_file_context_users(data, node); ck_assert_ptr_null(res); free(res); free_all_maps(); free(data->mod_name); free(data); free_policy_node(node); } END_TEST START_TEST (test_check_file_context_error_nodes) { struct check_data *data = malloc(sizeof(struct check_data)); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_FC_ENTRY; struct check_result *res = check_file_context_error_nodes(data, node); ck_assert_ptr_null(res); node->flavor = NODE_ERROR; res = check_file_context_error_nodes(data, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'E'); ck_assert_int_eq(res->check_id, E_ID_FC_ERROR); ck_assert_ptr_nonnull(res->message); free_check_result(res); free(data->mod_name); free(data); free_policy_node(node); } END_TEST START_TEST (test_fc_checks_handle_null_context_fields) { struct check_data *data = malloc(sizeof(struct check_data)); data->filename = strdup("foo"); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_FC_ENTRY; struct fc_entry *entry = malloc(sizeof(struct fc_entry)); memset(entry, 0, sizeof(struct fc_entry)); node->data.fc_data = entry; ck_assert_ptr_null(check_file_context_types_exist(data, node)); ck_assert_ptr_null(check_file_context_types_in_mod(data, node)); ck_assert_ptr_null(check_file_context_roles(data, node)); ck_assert_ptr_null(check_file_context_users(data, node)); free(data->filename); free(data->mod_name); free(data); free_policy_node(node); } END_TEST START_TEST (test_check_file_context_regex) { struct check_data *data = malloc(sizeof(struct check_data)); data->mod_name = strdup("foo"); data->flavor = FILE_FC_FILE; struct policy_node *node = malloc(sizeof(struct policy_node)); memset(node, 0, sizeof(struct policy_node)); node->flavor = NODE_FC_ENTRY; struct fc_entry *entry = malloc(sizeof(struct fc_entry)); memset(entry, 0, sizeof(struct fc_entry)); entry->context = malloc(sizeof(struct sel_context)); memset(entry->context, 0, sizeof(struct sel_context)); entry->path = strdup("path.with.unescpaed.dots"); node->data.fc_data = entry; struct check_result *res = check_file_context_regex(data, node); ck_assert_ptr_nonnull(res); ck_assert_int_eq(res->severity, 'W'); ck_assert_int_eq(res->check_id, W_ID_FC_REGEX); ck_assert_ptr_nonnull(res->message); free_check_result(res); free(entry->path); entry->path = strdup("path\\.with\\.escaped\\.dots"); res = check_file_context_regex(data, node); ck_assert_ptr_null(res); free(entry->path); entry->path = strdup("brackets\\.are[.s.kipped.]\\."); res = check_file_context_regex(data, node); ck_assert_ptr_null(res); free(entry->path); entry->path = strdup("unclosed[bracket"); res = check_file_context_regex(data, node); ck_assert_ptr_null(res); free(entry->path); entry->path = strdup("escaped[brackets\\]in.brackets]"); res = check_file_context_regex(data, node); ck_assert_ptr_null(res); free(data->mod_name); free(data); free_policy_node(node); } END_TEST static Suite *fc_checks_suite(void) { Suite *s; TCase *tc_core; s = suite_create("FC_Checks"); tc_core = tcase_create("Core"); tcase_add_test(tc_core, test_check_file_context_types_exist); tcase_add_test(tc_core, test_check_file_context_types_exist_bad_flavor); tcase_add_test(tc_core, test_check_file_context_types_in_mod); tcase_add_test(tc_core, test_check_file_context_roles); tcase_add_test(tc_core, test_check_file_context_users); tcase_add_test(tc_core, test_check_file_context_error_nodes); tcase_add_test(tc_core, test_check_file_context_regex); tcase_add_test(tc_core, test_fc_checks_handle_null_context_fields); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed = 0; Suite *s; SRunner *sr; s = fc_checks_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0)? 0 : -1; } selint-1.2.1/Makefile.in0000644000175100001710000006746514167117365012031 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(selintconfdir)" DATA = $(selintconf_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = src . man tests am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in INSTALL \ README compile install-sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_VALGRIND_drd = @ENABLE_VALGRIND_drd@ ENABLE_VALGRIND_helgrind = @ENABLE_VALGRIND_helgrind@ ENABLE_VALGRIND_memcheck = @ENABLE_VALGRIND_memcheck@ ENABLE_VALGRIND_sgcheck = @ENABLE_VALGRIND_sgcheck@ EXEEXT = @EXEEXT@ GREP = @GREP@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGES = @MANPAGES@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VALGRIND = @VALGRIND@ VALGRIND_ENABLED = @VALGRIND_ENABLED@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ valgrind_enabled_tools = @valgrind_enabled_tools@ valgrind_tools = @valgrind_tools@ AUTOMAKE_OPTIONS = foreign @WITH_CHECK_FALSE@SUBDIRS = src . man @WITH_CHECK_TRUE@SUBDIRS = src . tests . man selintconfdir = $(sysconfdir) selintconf_DATA = selint.conf EXTRA_DIST = selint.conf CHANGELOG LICENSE NOTICE check_examples.txt all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-selintconfDATA: $(selintconf_DATA) @$(NORMAL_INSTALL) @list='$(selintconf_DATA)'; test -n "$(selintconfdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(selintconfdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(selintconfdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(selintconfdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(selintconfdir)" || exit $$?; \ done uninstall-selintconfDATA: @$(NORMAL_UNINSTALL) @list='$(selintconf_DATA)'; test -n "$(selintconfdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(selintconfdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 @WITH_CHECK_TRUE@check-local: check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile $(DATA) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(selintconfdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-selintconfDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-selintconfDATA .MAKE: $(am__recursive_targets) all check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am check-local clean clean-cscope \ clean-generic cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-hdr distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-selintconfDATA install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-selintconfDATA .PRECIOUS: Makefile @WITH_CHECK_TRUE@check-valgrind: @WITH_CHECK_TRUE@ CK_FORK=no $(MAKE) -C tests check-valgrind-memcheck-am @WITH_CHECK_FALSE@check-local: @WITH_CHECK_FALSE@ @echo "SELint was configured without Check support!!" @WITH_CHECK_FALSE@ @exit 1 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: selint-1.2.1/Makefile.am0000644000175100001710000000170614167117255012000 00000000000000# Copyright 2019 Tresys Technology, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. AUTOMAKE_OPTIONS = foreign if WITH_CHECK SUBDIRS = src . tests . man check-valgrind: CK_FORK=no $(MAKE) -C tests check-valgrind-memcheck-am else SUBDIRS = src . man check-local: @echo "SELint was configured without Check support!!" @exit 1 endif selintconfdir = $(sysconfdir) selintconf_DATA = selint.conf EXTRA_DIST = selint.conf CHANGELOG LICENSE NOTICE check_examples.txt