mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00

BugLink: https://launchpad.net/bugs/1588069 Currently change_profile /** -> A, change_profile unsafe /** -> A, do not conflict because the safe rules only set the change_profile permission where the unsafe set unsafe exec. To fix this we have the safe version set exec bits as well with out setting unsafe exec. This allows the exec conflict logic to detect any conflicts. This is safe to do even for older kernels as the exec bits off of the 2nd term encoding in the change_onexec rules are unused. Test files tst/simple_tests/change_profile/onx_no_conflict_safe1.sd tst/simple_tests/change_profile/onx_no_conflict_safe2.sd by Christian Boltz <apparmor@cboltz.de> Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Tyler Hicks <tyhicks@canonical.com>
560 lines
22 KiB
Bash
Executable file
560 lines
22 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Copyright (c) 2013
|
|
# Canonical, Ltd. (All rights reserved)
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of version 2 of the GNU General Public
|
|
# License published by the Free Software Foundation.
|
|
#
|
|
# 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, contact Canonical Ltd.
|
|
#
|
|
|
|
# Tests for post-parser equality among multiple profiles. These tests are
|
|
# useful to verify that keyword aliases, formatting differences, etc., all
|
|
# result in the same parser output.
|
|
|
|
set -o pipefail
|
|
|
|
_SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}" )
|
|
|
|
APPARMOR_PARSER="${APPARMOR_PARSER:-${_SCRIPTDIR}/../apparmor_parser}"
|
|
fails=0
|
|
errors=0
|
|
verbose="${VERBOSE:-}"
|
|
|
|
hash_binary_policy()
|
|
{
|
|
printf %s "$1" | ${APPARMOR_PARSER} --features-file ${_SCRIPTDIR}/features_files/features.all -qS 2>/dev/null| md5sum | cut -d ' ' -f 1
|
|
return $?
|
|
}
|
|
|
|
# verify_binary - compares the binary policy of multiple profiles
|
|
# $1: Test type (equality or inequality)
|
|
# $2: A short description of the test
|
|
# $3: The known-good profile
|
|
# $4..$n: The profiles to compare against $3
|
|
#
|
|
# Upon failure/error, prints out the test description and profiles that failed
|
|
# and increments $fails or $errors for each failure and error, respectively
|
|
verify_binary()
|
|
{
|
|
local t=$1
|
|
local desc=$2
|
|
local good_profile=$3
|
|
local good_hash
|
|
local ret=0
|
|
|
|
shift
|
|
shift
|
|
shift
|
|
|
|
if [ "$t" != "equality" ] && [ "$t" != "inequality" ]
|
|
then
|
|
printf "\nERROR: Unknown test mode:\n%s\n\n" "$t" 1>&2
|
|
((errors++))
|
|
return $((ret + 1))
|
|
fi
|
|
|
|
if [ -n "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi
|
|
good_hash=$(hash_binary_policy "$good_profile")
|
|
if [ $? -ne 0 ]
|
|
then
|
|
if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi
|
|
printf "\nERROR: Error hashing the following \"known-good\" profile:\n%s\n\n" \
|
|
"$good_profile" 1>&2
|
|
((errors++))
|
|
return $((ret + 1))
|
|
fi
|
|
|
|
for profile in "$@"
|
|
do
|
|
hash=$(hash_binary_policy "$profile")
|
|
if [ $? -ne 0 ]
|
|
then
|
|
if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi
|
|
printf "\nERROR: Error hashing the following profile:\n%s\n\n" \
|
|
"$profile" 1>&2
|
|
((errors++))
|
|
((ret++))
|
|
elif [ "$t" == "equality" ] && [ "$hash" != "$good_hash" ]
|
|
then
|
|
if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi
|
|
printf "\nFAIL: Hash values do not match\n" 2>&1
|
|
printf "known-good (%s) != profile-under-test (%s) for the following profile:\n%s\n\n" \
|
|
"$good_hash" "$hash" "$profile" 1>&2
|
|
((fails++))
|
|
((ret++))
|
|
elif [ "$t" == "inequality" ] && [ "$hash" == "$good_hash" ]
|
|
then
|
|
if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi
|
|
printf "\nFAIL: Hash values match\n" 2>&1
|
|
printf "known-good (%s) == profile-under-test (%s) for the following profile:\n%s\n\n" \
|
|
"$good_hash" "$hash" "$profile" 1>&2
|
|
((fails++))
|
|
((ret++))
|
|
fi
|
|
done
|
|
|
|
if [ $ret -eq 0 ]
|
|
then
|
|
if [ -z "$verbose" ] ; then
|
|
printf "."
|
|
else
|
|
printf " ok\n"
|
|
|
|
fi
|
|
fi
|
|
return $ret
|
|
}
|
|
|
|
verify_binary_equality()
|
|
{
|
|
verify_binary "equality" "$@"
|
|
}
|
|
|
|
verify_binary_inequality()
|
|
{
|
|
verify_binary "inequality" "$@"
|
|
}
|
|
|
|
printf "Equality Tests:\n"
|
|
|
|
verify_binary_equality "dbus send" \
|
|
"/t { dbus send, }" \
|
|
"/t { dbus write, }" \
|
|
"/t { dbus w, }"
|
|
|
|
verify_binary_equality "dbus receive" \
|
|
"/t { dbus receive, }" \
|
|
"/t { dbus read, }" \
|
|
"/t { dbus r, }"
|
|
|
|
verify_binary_equality "dbus send + receive" \
|
|
"/t { dbus (send, receive), }" \
|
|
"/t { dbus (read, write), }" \
|
|
"/t { dbus (r, w), }" \
|
|
"/t { dbus (rw), }" \
|
|
"/t { dbus rw, }" \
|
|
|
|
verify_binary_equality "dbus all accesses" \
|
|
"/t { dbus (send, receive, bind, eavesdrop), }" \
|
|
"/t { dbus (read, write, bind, eavesdrop), }" \
|
|
"/t { dbus (r, w, bind, eavesdrop), }" \
|
|
"/t { dbus (rw, bind, eavesdrop), }" \
|
|
"/t { dbus (), }" \
|
|
"/t { dbus, }" \
|
|
|
|
verify_binary_equality "dbus implied accesses with a bus conditional" \
|
|
"/t { dbus (send, receive, bind, eavesdrop) bus=session, }" \
|
|
"/t { dbus (read, write, bind, eavesdrop) bus=session, }" \
|
|
"/t { dbus (r, w, bind, eavesdrop) bus=session, }" \
|
|
"/t { dbus (rw, bind, eavesdrop) bus=session, }" \
|
|
"/t { dbus () bus=session, }" \
|
|
"/t { dbus bus=session, }" \
|
|
|
|
verify_binary_equality "dbus implied accesses for services" \
|
|
"/t { dbus bind name=com.foo, }" \
|
|
"/t { dbus name=com.foo, }"
|
|
|
|
verify_binary_equality "dbus implied accesses for messages" \
|
|
"/t { dbus (send, receive) path=/com/foo interface=org.foo, }" \
|
|
"/t { dbus path=/com/foo interface=org.foo, }"
|
|
|
|
verify_binary_equality "dbus implied accesses for messages with peer names" \
|
|
"/t { dbus (send, receive) path=/com/foo interface=org.foo peer=(name=com.foo), }" \
|
|
"/t { dbus path=/com/foo interface=org.foo peer=(name=com.foo), }" \
|
|
"/t { dbus (send, receive) path=/com/foo interface=org.foo peer=(name=(com.foo)), }" \
|
|
"/t { dbus path=/com/foo interface=org.foo peer=(name=(com.foo)), }"
|
|
|
|
verify_binary_equality "dbus implied accesses for messages with peer labels" \
|
|
"/t { dbus (send, receive) path=/com/foo interface=org.foo peer=(label=/usr/bin/app), }" \
|
|
"/t { dbus path=/com/foo interface=org.foo peer=(label=/usr/bin/app), }"
|
|
|
|
verify_binary_equality "dbus element parsing" \
|
|
"/t { dbus bus=b path=/ interface=i member=m peer=(name=n label=l), }" \
|
|
"/t { dbus bus=\"b\" path=\"/\" interface=\"i\" member=\"m\" peer=(name=\"n\" label=\"l\"), }" \
|
|
"/t { dbus bus=(b) path=(/) interface=(i) member=(m) peer=(name=(n) label=(l)), }" \
|
|
"/t { dbus bus=(\"b\") path=(\"/\") interface=(\"i\") member=(\"m\") peer=(name=(\"n\") label=(\"l\")), }" \
|
|
"/t { dbus bus =b path =/ interface =i member =m peer =(name =n label =l), }" \
|
|
"/t { dbus bus= b path= / interface= i member= m peer= (name= n label= l), }" \
|
|
"/t { dbus bus = b path = / interface = i member = m peer = ( name = n label = l ), }"
|
|
|
|
verify_binary_equality "dbus access parsing" \
|
|
"/t { dbus, }" \
|
|
"/t { dbus (), }" \
|
|
"/t { dbus (send, receive, bind, eavesdrop), }" \
|
|
"/t { dbus (send receive bind eavesdrop), }" \
|
|
"/t { dbus (send, receive bind, eavesdrop), }" \
|
|
"/t { dbus (send,receive,bind,eavesdrop), }" \
|
|
"/t { dbus (send,receive,,,,,,,,,,,,,,,,bind,eavesdrop), }" \
|
|
"/t { dbus (send,send,send,send send receive,bind eavesdrop), }" \
|
|
|
|
verify_binary_equality "dbus variable expansion" \
|
|
"/t { dbus (send, receive) path=/com/foo member=spork interface=org.foo peer=(name=com.foo label=/com/foo), }" \
|
|
"@{FOO}=foo
|
|
/t { dbus (send, receive) path=/com/@{FOO} member=spork interface=org.@{FOO} peer=(name=com.@{FOO} label=/com/@{FOO}), }" \
|
|
"@{FOO}=foo
|
|
@{SPORK}=spork
|
|
/t { dbus (send, receive) path=/com/@{FOO} member=@{SPORK} interface=org.@{FOO} peer=(name=com.@{FOO} label=/com/@{FOO}), }" \
|
|
"@{FOO}=/com/foo
|
|
/t { dbus (send, receive) path=@{FOO} member=spork interface=org.foo peer=(name=com.foo label=@{FOO}), }" \
|
|
"@{FOO}=com
|
|
/t { dbus (send, receive) path=/@{FOO}/foo member=spork interface=org.foo peer=(name=@{FOO}.foo label=/@{FOO}/foo), }"
|
|
|
|
verify_binary_equality "dbus variable expansion, multiple values/rules" \
|
|
"/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, }" \
|
|
"/t { dbus (send, receive) path=/com/{foo,bar}, }" \
|
|
"/t { dbus (send, receive) path={/com/foo,/com/bar}, }" \
|
|
"@{FOO}=foo
|
|
/t { dbus (send, receive) path=/com/@{FOO}, dbus (send, receive) path=/com/bar, }" \
|
|
"@{FOO}=foo bar
|
|
/t { dbus (send, receive) path=/com/@{FOO}, }" \
|
|
"@{FOO}=bar foo
|
|
/t { dbus (send, receive) path=/com/@{FOO}, }" \
|
|
"@{FOO}={bar,foo}
|
|
/t { dbus (send, receive) path=/com/@{FOO}, }" \
|
|
"@{FOO}=foo
|
|
@{BAR}=bar
|
|
/t { dbus (send, receive) path=/com/{@{FOO},@{BAR}}, }" \
|
|
|
|
verify_binary_equality "dbus variable expansion, ensure rule de-duping occurs" \
|
|
"/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, }" \
|
|
"/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, dbus (send, receive) path=/com/bar, }" \
|
|
"@{FOO}=bar foo bar foo
|
|
/t { dbus (send, receive) path=/com/@{FOO}, }" \
|
|
"@{FOO}=bar foo bar foo
|
|
/t { dbus (send, receive) path=/com/@{FOO}, dbus (send, receive) path=/com/@{FOO}, }"
|
|
|
|
verify_binary_equality "dbus minimization with all perms" \
|
|
"/t { dbus, }" \
|
|
"/t { dbus bus=session, dbus, }" \
|
|
"/t { dbus (send, receive, bind, eavesdrop), dbus, }"
|
|
|
|
verify_binary_equality "dbus minimization with bind" \
|
|
"/t { dbus bind, }" \
|
|
"/t { dbus bind bus=session, dbus bind, }" \
|
|
"/t { dbus bind bus=system name=com.foo, dbus bind, }"
|
|
|
|
verify_binary_equality "dbus minimization with send and a bus conditional" \
|
|
"/t { dbus send bus=system, }" \
|
|
"/t { dbus send bus=system path=/com/foo interface=com.foo member=bar, dbus send bus=system, }" \
|
|
"/t { dbus send bus=system peer=(label=/usr/bin/foo), dbus send bus=system, }"
|
|
|
|
verify_binary_equality "dbus minimization with an audit modifier" \
|
|
"/t { audit dbus eavesdrop, }" \
|
|
"/t { audit dbus eavesdrop bus=session, audit dbus eavesdrop, }"
|
|
|
|
verify_binary_equality "dbus minimization with a deny modifier" \
|
|
"/t { deny dbus send bus=system peer=(name=com.foo), }" \
|
|
"/t { deny dbus send bus=system peer=(name=com.foo label=/usr/bin/foo), deny dbus send bus=system peer=(name=com.foo), }" \
|
|
|
|
verify_binary_equality "dbus minimization found in dbus abstractions" \
|
|
"/t { dbus send bus=session, }" \
|
|
"/t { dbus send
|
|
bus=session
|
|
path=/org/freedesktop/DBus
|
|
interface=org.freedesktop.DBus
|
|
member={Hello,AddMatch,RemoveMatch,GetNameOwner,NameHasOwner,StartServiceByName}
|
|
peer=(name=org.freedesktop.DBus),
|
|
dbus send bus=session, }"
|
|
|
|
# Rules compatible with audit, deny, and audit deny
|
|
# note: change_profile does not support audit/allow/deny atm
|
|
for rule in "capability" "capability mac_admin" \
|
|
"network" "network tcp" "network inet6 tcp"\
|
|
"mount" "mount /a" "mount /a -> /b" "mount options in (ro) /a -> b" \
|
|
"remount" "remount /a" \
|
|
"umount" "umount /a" \
|
|
"pivot_root" "pivot_root /a" "pivot_root oldroot=/" \
|
|
"pivot_root oldroot=/ /a" "pivot_root oldroot=/ /a -> foo" \
|
|
"ptrace" "ptrace trace" "ptrace (readby,tracedby) peer=unconfined" \
|
|
"signal" "signal (send,receive)" "signal peer=unconfined" \
|
|
"signal receive set=(kill)" \
|
|
"dbus" "dbus send" "dbus bus=system" "dbus bind name=foo" \
|
|
"dbus peer=(label=foo)" "dbus eavesdrop" \
|
|
"unix" "unix (create, listen, accept)" "unix addr=@*" "unix addr=none" \
|
|
"unix peer=(label=foo)" \
|
|
"/f r" "/f w" "/f rwmlk" "/** r" "/**/ w" \
|
|
"file /f r" "file /f w" "file /f rwmlk" \
|
|
"link /a -> /b" "link subset /a -> /b" \
|
|
"l /a -> /b" "l subset /a -> /b" \
|
|
"file l /a -> /b" "l subset /a -> /b"
|
|
do
|
|
verify_binary_equality "allow modifier for \"${rule}\"" \
|
|
"/t { ${rule}, }" \
|
|
"/t { allow ${rule}, }"
|
|
|
|
verify_binary_equality "audit allow modifier for \"${rule}\"" \
|
|
"/t { audit ${rule}, }" \
|
|
"/t { audit allow ${rule}, }"
|
|
|
|
verify_binary_inequality "audit, deny, and audit deny modifiers for \"${rule}\"" \
|
|
"/t { ${rule}, }" \
|
|
"/t { audit ${rule}, }" \
|
|
"/t { audit allow ${rule}, }" \
|
|
"/t { deny ${rule}, }" \
|
|
"/t { audit deny ${rule}, }"
|
|
|
|
verify_binary_inequality "audit vs deny and audit deny modifiers for \"${rule}\"" \
|
|
"/t { audit ${rule}, }" \
|
|
"/t { deny ${rule}, }" \
|
|
"/t { audit deny ${rule}, }"
|
|
|
|
verify_binary_inequality "deny and audit deny modifiers for \"${rule}\"" \
|
|
"/t { deny ${rule}, }" \
|
|
"/t { audit deny ${rule}, }"
|
|
done
|
|
|
|
# Rules that need special treatment for the deny modifier
|
|
for rule in "/f ux" "/f Ux" "/f px" "/f Px" "/f cx" "/f Cx" "/f ix" \
|
|
"/f pux" "/f Pux" "/f pix" "/f Pix" \
|
|
"/f cux" "/f Cux" "/f cix" "/f Cix" \
|
|
"/* ux" "/* Ux" "/* px" "/* Px" "/* cx" "/* Cx" "/* ix" \
|
|
"/* pux" "/* Pux" "/* pix" "/* Pix" \
|
|
"/* cux" "/* Cux" "/* cix" "/* Cix" \
|
|
"/f px -> b " "/f Px -> b" "/f cx -> b" "/f Cx -> b" \
|
|
"/f pux -> b" "/f Pux -> b" "/f pix -> b" "/f Pix -> b" \
|
|
"/f cux -> b" "/f Cux -> b" "/f cix -> b" "/f Cix -> b" \
|
|
"/* px -> b" "/* Px -> b" "/* cx -> b" "/* Cx -> b" \
|
|
"/* pux -> b" "/* Pux -> b" "/* pix -> b" "/* Pix -> b" \
|
|
"/* cux -> b" "/* Cux -> b" "/* cix -> b" "/* Cix -> b" \
|
|
"file /f ux" "file /f Ux" "file /f px" "file /f Px" \
|
|
"file /f cx" "file /f Cx" "file /f ix" \
|
|
"file /f pux" "file /f Pux" "file /f pix" "file /f Pix" \
|
|
"/f cux" "/f Cux" "/f cix" "/f Cix" \
|
|
"file /* ux" "file /* Ux" "file /* px" "file /* Px" \
|
|
"file /* cx" "file /* Cx" "file /* ix" \
|
|
"file /* pux" "file /* Pux" "file /* pix" "file /* Pix" \
|
|
"file /* cux" "file /* Cux" "file /* cix" "file /* Cix" \
|
|
"file /f px -> b " "file /f Px -> b" "file /f cx -> b" "file /f Cx -> b" \
|
|
"file /f pux -> b" "file /f Pux -> b" "file /f pix -> b" "file /f Pix -> b" \
|
|
"file /f cux -> b" "file /f Cux -> b" "file /f cix -> b" "file /f Cix -> b" \
|
|
"file /* px -> b" "file /* Px -> b" "file /* cx -> b" "file /* Cx -> b" \
|
|
"file /* pux -> b" "file /* Pux -> b" "file /* pix -> b" "file /* Pix -> b" \
|
|
"file /* cux -> b" "file /* Cux -> b" "file /* cix -> b" "file /* Cix -> b"
|
|
|
|
do
|
|
verify_binary_equality "allow modifier for \"${rule}\"" \
|
|
"/t { ${rule}, }" \
|
|
"/t { allow ${rule}, }"
|
|
|
|
verify_binary_equality "audit allow modifier for \"${rule}\"" \
|
|
"/t { audit ${rule}, }" \
|
|
"/t { audit allow ${rule}, }"
|
|
|
|
# skip rules that don't end with x perm
|
|
if [ -n "${rule##*x}" ] ; then continue ; fi
|
|
|
|
verify_binary_inequality "deny, audit deny modifier for \"${rule}\"" \
|
|
"/t { ${rule}, }" \
|
|
"/t { audit ${rule}, }" \
|
|
"/t { audit allow ${rule}, }" \
|
|
"/t { deny ${rule% *} x, }" \
|
|
"/t { audit deny ${rule% *} x, }"
|
|
|
|
verify_binary_inequality "audit vs deny and audit deny modifiers for \"${rule}\"" \
|
|
"/t { audit ${rule}, }" \
|
|
"/t { deny ${rule% *} x, }" \
|
|
"/t { audit deny ${rule% *} x, }"
|
|
|
|
done
|
|
|
|
# verify deny and audit deny differ for x perms
|
|
for prefix in "/f" "/*" "file /f" "file /*" ; do
|
|
verify_binary_inequality "deny and audit deny x modifiers for \"${prefix}\"" \
|
|
"/t { deny ${prefix} x, }" \
|
|
"/t { audit deny ${prefix} x, }"
|
|
done
|
|
|
|
#Test equality of leading and trailing file permissions
|
|
for audit in "" "audit" ; do
|
|
for allow in "" "allow" "deny" ; do
|
|
for owner in "" "owner" ; do
|
|
for f in "" "file" ; do
|
|
prefix="$audit $allow $owner $f"
|
|
for perm in "r" "w" "a" "l" "k" "m" "rw" "ra" \
|
|
"rl" "rk" "rm" "wl" "wk" "wm" \
|
|
"rwl" "rwk" "rwm" "ral" "rak" \
|
|
"ram" "rlk" "rlm" "rkm" "wlk" \
|
|
"wlm" "wkm" "alk" "alm" "akm" \
|
|
"lkm" "rwlk" "rwlm" "rwkm" \
|
|
"ralk" "ralm" "wlkm" "alkm" \
|
|
"rwlkm" "ralkm" ; do
|
|
verify_binary_equality "leading and trailing perms for \"${perm}\"" \
|
|
"/t { ${prefix} /f ${perm}, }" \
|
|
"/t { ${prefix} ${perm} /f, }"
|
|
done
|
|
if [ "$allow" == "deny" ] ; then continue ; fi
|
|
for perm in "ux" "Ux" "px" "Px" "cx" "Cx" \
|
|
"ix" "pux" "Pux" "pix" "Pix" \
|
|
"cux" "Cux" "cix" "Cix"
|
|
do
|
|
verify_binary_equality "leading and trailing perms for \"${perm}\"" \
|
|
"/t { ${prefix} /f ${perm}, }" \
|
|
"/t { ${prefix} ${perm} /f, }"
|
|
done
|
|
for perm in "px" "Px" "cx" "Cx" \
|
|
"pux" "Pux" "pix" "Pix" \
|
|
"cux" "Cux" "cix" "Cix"
|
|
do
|
|
verify_binary_equality "leading and trailing perms for x-transition \"${perm}\"" \
|
|
"/t { ${prefix} /f ${perm} -> b, }" \
|
|
"/t { ${prefix} ${perm} /f -> b, }"
|
|
done
|
|
done
|
|
done
|
|
done
|
|
done
|
|
|
|
#Test rule overlap for x most specific match
|
|
for perm1 in "ux" "Ux" "px" "Px" "cx" "Cx" "ix" "pux" "Pux" \
|
|
"pix" "Pix" "cux" "Cux" "cix" "Cix" "px -> b" \
|
|
"Px -> b" "cx -> b" "Cx -> b" "pux -> b" "Pux ->b" \
|
|
"pix -> b" "Pix -> b" "cux -> b" "Cux -> b" \
|
|
"cix -> b" "Cix -> b"
|
|
do
|
|
for perm2 in "ux" "Ux" "px" "Px" "cx" "Cx" "ix" "pux" "Pux" \
|
|
"pix" "Pix" "cux" "Cux" "cix" "Cix" "px -> b" \
|
|
"Px -> b" "cx -> b" "Cx -> b" "pux -> b" "Pux ->b" \
|
|
"pix -> b" "Pix -> b" "cux -> b" "Cux -> b" \
|
|
"cix -> b" "Cix -> b"
|
|
do
|
|
if [ "$perm1" == "$perm2" ] ; then
|
|
verify_binary_equality "Exec perm \"${perm1}\" - most specific match: same as glob" \
|
|
"/t { /* ${perm1}, /f ${perm2}, }" \
|
|
"/t { /* ${perm1}, }"
|
|
else
|
|
verify_binary_inequality "Exec \"${perm1}\" vs \"${perm2}\" - most specific match: different from glob" \
|
|
"/t { /* ${perm1}, /f ${perm2}, }" \
|
|
"/t { /* ${perm1}, }"
|
|
fi
|
|
done
|
|
verify_binary_inequality "Exec \"${perm1}\" vs deny x - most specific match: different from glob" \
|
|
"/t { /* ${perm1}, audit deny /f x, }" \
|
|
"/t { /* ${perm1}, }"
|
|
|
|
done
|
|
|
|
#Test deny carves out permission
|
|
verify_binary_inequality "Deny removes r perm" \
|
|
"/t { /foo/[abc] r, audit deny /foo/b r, }" \
|
|
"/t { /foo/[abc] r, }"
|
|
|
|
verify_binary_equality "Deny removes r perm" \
|
|
"/t { /foo/[abc] r, audit deny /foo/b r, }" \
|
|
"/t { /foo/[ac] r, }"
|
|
|
|
#this one may not be true in the future depending on if the compiled profile
|
|
#is explicitly including deny permissions for dynamic composition
|
|
verify_binary_equality "Deny of ungranted perm" \
|
|
"/t { /foo/[abc] r, audit deny /foo/b w, }" \
|
|
"/t { /foo/[abc] r, }"
|
|
|
|
|
|
verify_binary_equality "change_profile == change_profile -> **" \
|
|
"/t { change_profile, }" \
|
|
"/t { change_profile -> **, }"
|
|
|
|
verify_binary_equality "change_profile /** == change_profile /** -> **" \
|
|
"/t { change_profile /**, }" \
|
|
"/t { change_profile /** -> **, }"
|
|
|
|
verify_binary_equality "change_profile /** == change_profile /** -> **" \
|
|
"/t { change_profile unsafe /**, }" \
|
|
"/t { change_profile unsafe /** -> **, }"
|
|
|
|
verify_binary_equality "change_profile /** == change_profile /** -> **" \
|
|
"/t { change_profile /**, }" \
|
|
"/t { change_profile safe /** -> **, }"
|
|
|
|
verify_binary_inequality "change_profile /** == change_profile /** -> **" \
|
|
"/t { change_profile /**, }" \
|
|
"/t { change_profile unsafe /**, }"
|
|
|
|
verify_binary_equality "profile name is hname in rule" \
|
|
":ns:/hname { signal peer=/hname, }" \
|
|
":ns:/hname { signal peer=@{profile_name}, }"
|
|
|
|
verify_binary_inequality "profile name is NOT fq name in rule" \
|
|
":ns:/hname { signal peer=:ns:/hname, }" \
|
|
":ns:/hname { signal peer=@{profile_name}, }"
|
|
|
|
verify_binary_equality "profile name is hname in sub pofile rule" \
|
|
":ns:/hname { profile child { signal peer=/hname//child, } }" \
|
|
":ns:/hname { profile child { signal peer=@{profile_name}, } }"
|
|
|
|
verify_binary_inequality "profile name is NOT fq name in sub profile rule" \
|
|
":ns:/hname { profile child { signal peer=:ns:/hname//child, } }" \
|
|
":ns:/hname { profile child { signal peer=@{profile_name}, } }"
|
|
|
|
verify_binary_equality "profile name is hname in hat rule" \
|
|
":ns:/hname { ^child { signal peer=/hname//child, } }" \
|
|
":ns:/hname { ^child { signal peer=@{profile_name}, } }"
|
|
|
|
verify_binary_inequality "profile name is NOT fq name in hat rule" \
|
|
":ns:/hname { ^child { signal peer=:ns:/hname//child, } }" \
|
|
":ns:/hname { ^child { signal peer=@{profile_name}, } }"
|
|
|
|
verify_binary_equality "@{profile_name} is literal in peer" \
|
|
"/{a,b} { signal peer=/\{a,b\}, }" \
|
|
"/{a,b} { signal peer=@{profile_name}, }"
|
|
|
|
verify_binary_equality "@{profile_name} is literal in peer with pattern" \
|
|
"/{a,b} { signal peer={/\{a,b\},c}, }" \
|
|
"/{a,b} { signal peer={@{profile_name},c}, }"
|
|
|
|
verify_binary_inequality "@{profile_name} is not pattern in peer" \
|
|
"/{a,b} { signal peer=/{a,b}, }" \
|
|
"/{a,b} { signal peer=@{profile_name}, }"
|
|
|
|
verify_binary_equality "@{profile_name} is literal in peer with esc sequence" \
|
|
"/\\\\a { signal peer=/\\\\a, }" \
|
|
"/\\\\a { signal peer=@{profile_name}, }"
|
|
|
|
verify_binary_equality "@{profile_name} is literal in peer with esc alt sequence" \
|
|
"/\\{a,b\\},c { signal peer=/\\{a,b\\},c, }" \
|
|
"/\\{a,b\\},c { signal peer=@{profile_name}, }"
|
|
|
|
|
|
|
|
# verify rlimit data conversions
|
|
verify_binary_equality "set rlimit rttime <= 12 weeks" \
|
|
"/t { set rlimit rttime <= 12 weeks, }" \
|
|
"/t { set rlimit rttime <= $((12 * 7)) days, }" \
|
|
"/t { set rlimit rttime <= $((12 * 7 * 24)) hours, }" \
|
|
"/t { set rlimit rttime <= $((12 * 7 * 24 * 60)) minutes, }" \
|
|
"/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60)) seconds, }" \
|
|
"/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60 * 1000)) ms, }" \
|
|
"/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60 * 1000 * 1000)) us, }" \
|
|
"/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60 * 1000 * 1000)), }"
|
|
|
|
verify_binary_equality "set rlimit cpu <= 42 weeks" \
|
|
"/t { set rlimit cpu <= 42 weeks, }" \
|
|
"/t { set rlimit cpu <= $((42 * 7)) days, }" \
|
|
"/t { set rlimit cpu <= $((42 * 7 * 24)) hours, }" \
|
|
"/t { set rlimit cpu <= $((42 * 7 * 24 * 60)) minutes, }" \
|
|
"/t { set rlimit cpu <= $((42 * 7 * 24 * 60 * 60)) seconds, }" \
|
|
"/t { set rlimit cpu <= $((42 * 7 * 24 * 60 * 60)), }"
|
|
|
|
verify_binary_equality "set rlimit memlock <= 2GB" \
|
|
"/t { set rlimit memlock <= 2GB, }" \
|
|
"/t { set rlimit memlock <= $((2 * 1024)) MB, }" \
|
|
"/t { set rlimit memlock <= $((2 * 1024 * 1024)) KB, }" \
|
|
"/t { set rlimit memlock <= $((2 * 1024 * 1024 * 1024)) , }" \
|
|
|
|
if [ $fails -ne 0 -o $errors -ne 0 ]
|
|
then
|
|
printf "ERRORS: %d\nFAILS: %d\n" $errors $fails 2>&1
|
|
exit $(($fails + $errors))
|
|
fi
|
|
|
|
[ -z "${verbose}" ] && printf "\n"
|
|
printf "PASS\n"
|
|
exit 0
|