MAC/do: Add basic tests on setting rules
MFC after: 1 minute Sponsored by: The FreeBSD Foundation
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
TESTSDIR= ${TESTSBASE}/sys/mac
|
||||
|
||||
TESTS_SUBDIRS+= bsdextended
|
||||
TESTS_SUBDIRS+= do
|
||||
TESTS_SUBDIRS+= ipacl
|
||||
TESTS_SUBDIRS+= portacl
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
PACKAGE= tests
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/sys/mac/do
|
||||
|
||||
ATF_TESTS_SH+= valid_configs invalid_configs
|
||||
|
||||
${PACKAGE}FILES+= common.sh
|
||||
|
||||
TEST_METADATA+= execenv="jail"
|
||||
TEST_METADATA+= required_kmods="mac_do"
|
||||
TEST_METADATA+= required_user="root"
|
||||
TEST_METADATA+= required_programs="sysctl"
|
||||
|
||||
.include <bsd.test.mk>
|
||||
@@ -0,0 +1,72 @@
|
||||
#
|
||||
# Copyright (c) 2026, The FreeBSD Foundation
|
||||
#
|
||||
# This software was developed by Olivier Certner <olce@FreeBSD.org> at
|
||||
# Kumacom SARL under sponsorship from the FreeBSD Foundation.
|
||||
|
||||
rules_parameter()
|
||||
{
|
||||
echo "$1".rules
|
||||
}
|
||||
|
||||
|
||||
CONF_ROOT_KNOB=security.mac.do
|
||||
RULES_KNOB=$(rules_parameter ${CONF_ROOT_KNOB})
|
||||
PPE_KNOB=${CONF_ROOT_KNOB}.print_parse_error
|
||||
|
||||
|
||||
# $1 = knob name, $2 = value
|
||||
sysctl_set_and_check()
|
||||
{
|
||||
local knob value
|
||||
|
||||
knob=$1
|
||||
value=$2
|
||||
atf_check -o ignore sysctl "$knob"="$value"
|
||||
atf_check -o inline:"$value\n" sysctl -n "$knob"
|
||||
}
|
||||
|
||||
# $1 = knob name, $2 = value
|
||||
sysctl_set_and_check_fails()
|
||||
{
|
||||
local knob value orig_value
|
||||
|
||||
knob=$1
|
||||
value=$2
|
||||
orig_value=$(sysctl -n "$knob")
|
||||
atf_check -s not-exit:0 -o ignore -e ignore sysctl "$knob"="$value"
|
||||
atf_check -o inline:"${orig_value}\n" sysctl -n "$knob"
|
||||
}
|
||||
|
||||
# $1 = sysctl function, $2 = value
|
||||
sysctl_set_and_check_rules_common()
|
||||
{
|
||||
local func value
|
||||
|
||||
func=$1
|
||||
value=$2
|
||||
"$func" ${RULES_KNOB} "$value"
|
||||
# Same spec but using the older in-rule separator (':')
|
||||
"$func" ${RULES_KNOB} "$(echo "$value" | sed 's%>%:%')"
|
||||
}
|
||||
|
||||
# $1 = value
|
||||
sysctl_set_and_check_rules()
|
||||
{
|
||||
local value
|
||||
|
||||
value=$1
|
||||
sysctl_set_and_check_rules_common sysctl_set_and_check "$value"
|
||||
}
|
||||
|
||||
# $1 = value
|
||||
sysctl_set_and_check_fails_rules()
|
||||
{
|
||||
local value
|
||||
|
||||
value=$1
|
||||
sysctl_set_and_check_rules_common sysctl_set_and_check_fails "$value"
|
||||
}
|
||||
|
||||
# Do not pollute kernel logs with parse errors
|
||||
sysctl $PPE_KNOB=0 >/dev/null 2>&1
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
#
|
||||
# Copyright (c) 2026, The FreeBSD Foundation
|
||||
#
|
||||
# This software was developed by Olivier Certner <olce@FreeBSD.org> at
|
||||
# Kumacom SARL under sponsorship from the FreeBSD Foundation.
|
||||
|
||||
atf_test_case rule_no_target_part
|
||||
rule_no_target_part_head()
|
||||
{
|
||||
atf_set descr "Missing target part in a rule"
|
||||
}
|
||||
rule_no_target_part_body()
|
||||
{
|
||||
sysctl_set_and_check_fails_rules "uid=0>"
|
||||
sysctl_set_and_check_fails_rules "gid=0>"
|
||||
sysctl_set_and_check_fails_rules "uid=0"
|
||||
sysctl_set_and_check_fails_rules "gid=0"
|
||||
}
|
||||
|
||||
atf_test_case rule_no_match_part
|
||||
rule_no_match_part_head()
|
||||
{
|
||||
atf_set descr "Missing match part in a rule"
|
||||
}
|
||||
rule_no_match_part_body()
|
||||
{
|
||||
sysctl_set_and_check_fails_rules ">uid=0"
|
||||
sysctl_set_and_check_fails_rules ">gid=0"
|
||||
}
|
||||
|
||||
atf_test_case rule_space_between_flag_and_gid_fail
|
||||
rule_space_between_flag_and_gid_fail_head()
|
||||
{
|
||||
atf_set descr "No space allowed between flag and GID"
|
||||
}
|
||||
rule_space_between_flag_and_gid_fail_body()
|
||||
{
|
||||
sysctl_set_and_check_fails_rules "uid=1001>uid=0,gid=0,+ gid=0"
|
||||
}
|
||||
|
||||
atf_test_case rule_user_names_fail
|
||||
rule_user_names_fail_head()
|
||||
{
|
||||
atf_set descr "Reject user names (only numerical IDs supported)"
|
||||
}
|
||||
rule_user_names_fail_body()
|
||||
{
|
||||
sysctl_set_and_check_fails_rules "uid=user>uid=0"
|
||||
sysctl_set_and_check_fails_rules "uid=1001>uid=root"
|
||||
}
|
||||
|
||||
atf_test_case rule_group_names_fail
|
||||
rule_group_names_fail_head()
|
||||
{
|
||||
atf_set descr "Reject group names (only numerical IDs supported)"
|
||||
}
|
||||
rule_group_names_fail_body()
|
||||
{
|
||||
sysctl_set_and_check_fails_rules "gid=group>gid=0"
|
||||
sysctl_set_and_check_fails_rules "gid=1001>gid=root"
|
||||
sysctl_set_and_check_fails_rules "gid=1001>gid=0,+gid=operator"
|
||||
}
|
||||
|
||||
atf_test_case rules_wrong_separator
|
||||
rules_wrong_separator_head()
|
||||
{
|
||||
atf_set descr "Wrong rules separator"
|
||||
}
|
||||
rules_wrong_separator_body()
|
||||
{
|
||||
sysctl_set_and_check_fails_rules "uid=1001>gid=0:gid=1001>gid=5"
|
||||
}
|
||||
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
. $(atf_get_srcdir)/common.sh
|
||||
|
||||
atf_add_test_case rule_no_target_part
|
||||
atf_add_test_case rule_no_match_part
|
||||
atf_add_test_case rule_space_between_flag_and_gid_fail
|
||||
atf_add_test_case rule_user_names_fail
|
||||
atf_add_test_case rule_group_names_fail
|
||||
atf_add_test_case rules_wrong_separator
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
#
|
||||
# Copyright (c) 2026, The FreeBSD Foundation
|
||||
#
|
||||
# This software was developed by Olivier Certner <olce@FreeBSD.org> at
|
||||
# Kumacom SARL under sponsorship from the FreeBSD Foundation.
|
||||
|
||||
atf_test_case rule_uid_to_any
|
||||
rule_uid_to_any_head()
|
||||
{
|
||||
atf_set descr "Single \"to any\" rule"
|
||||
}
|
||||
rule_uid_to_any_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>any"
|
||||
sysctl_set_and_check_rules "gid=1001>any"
|
||||
}
|
||||
|
||||
atf_test_case rule_uid_to_uid
|
||||
rule_uid_to_uid_head()
|
||||
{
|
||||
atf_set descr "Single \"to UID\" rule"
|
||||
}
|
||||
rule_uid_to_uid_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>uid=0"
|
||||
sysctl_set_and_check_rules "gid=1001>uid=0"
|
||||
}
|
||||
|
||||
atf_test_case rule_uid_to_uid_any
|
||||
rule_uid_to_uid_any_head()
|
||||
{
|
||||
atf_set descr "Single \"to UID any\" rule"
|
||||
}
|
||||
rule_uid_to_uid_any_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>uid=any"
|
||||
sysctl_set_and_check_rules "gid=1001>uid=any"
|
||||
}
|
||||
|
||||
atf_test_case rule_uid_to_uid_star
|
||||
rule_uid_to_uid_star_head()
|
||||
{
|
||||
atf_set descr "Single \"to any (with '*')\" rule"
|
||||
}
|
||||
rule_uid_to_uid_star_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>uid=*"
|
||||
sysctl_set_and_check_rules "gid=1001>uid=*"
|
||||
}
|
||||
|
||||
atf_test_case rule_uid_to_uid_gid
|
||||
rule_uid_to_uid_gid_head()
|
||||
{
|
||||
atf_set descr "Single \"to UID and GID\" rule"
|
||||
}
|
||||
rule_uid_to_uid_gid_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>uid=0,gid=0"
|
||||
sysctl_set_and_check_rules "gid=1001>uid=0,gid=0"
|
||||
}
|
||||
|
||||
atf_test_case rule_uid_to_uid_gid_optional_sgid
|
||||
rule_uid_to_uid_gid_optional_sgid_head()
|
||||
{
|
||||
atf_set descr "Single \"to UID, GID and \
|
||||
optional supplementary group rule\" rule"
|
||||
}
|
||||
rule_uid_to_uid_gid_optional_sgid_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>uid=0,gid=0,+gid=0"
|
||||
sysctl_set_and_check_rules "gid=1001>uid=0,gid=0,+gid=0"
|
||||
}
|
||||
|
||||
atf_test_case rule_uid_to_uid_gid_mandatory_sgid
|
||||
rule_uid_to_uid_gid_mandatory_sgid_head()
|
||||
{
|
||||
atf_set descr "Single \"to UID, GID and \
|
||||
mandatory supplementary group\" rule"
|
||||
}
|
||||
rule_uid_to_uid_gid_mandatory_sgid_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>uid=0,gid=0,!gid=0"
|
||||
sysctl_set_and_check_rules "gid=1001>uid=0,gid=0,!gid=0"
|
||||
}
|
||||
|
||||
atf_test_case rule_uid_to_uid_gid_excluded_sgid
|
||||
rule_uid_to_uid_gid_excluded_sgid_head()
|
||||
{
|
||||
atf_set descr "Single \"to UID, GID and excluded supplementary group\" rule"
|
||||
}
|
||||
rule_uid_to_uid_gid_excluded_sgid_body()
|
||||
{
|
||||
sysctl_set_and_check_rules "uid=1001>uid=0,gid=0,-gid=0"
|
||||
sysctl_set_and_check_rules "gid=1001>uid=0,gid=0,-gid=0"
|
||||
}
|
||||
|
||||
atf_test_case rules_uid_to_uid
|
||||
rules_uid_to_uid_head()
|
||||
{
|
||||
atf_set descr "Multiple \"to UID\" rules"
|
||||
}
|
||||
rules_uid_to_uid_body() {
|
||||
sysctl_set_and_check_rules \
|
||||
"uid=1001>uid=0;uid=1001>uid=0,gid=0,!gid=0,+gid=5;gid=1001>gid=5"
|
||||
}
|
||||
|
||||
atf_test_case rules_uid_to_uid_with_spaces
|
||||
rules_uid_to_uid_with_spaces_head()
|
||||
{
|
||||
atf_set descr "Multiple \"to UID\" rules with extra spaces"
|
||||
}
|
||||
rules_uid_to_uid_with_spaces_body()
|
||||
{
|
||||
sysctl_set_and_check_rules \
|
||||
"uid=1001 > uid=0; uid=1001>uid=0, gid = 0, !gid =0,+gid =5; \
|
||||
gid= 1001 >gid =5"
|
||||
}
|
||||
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
. $(atf_get_srcdir)/common.sh
|
||||
|
||||
atf_add_test_case rule_uid_to_any
|
||||
atf_add_test_case rule_uid_to_uid
|
||||
atf_add_test_case rule_uid_to_uid_any
|
||||
atf_add_test_case rule_uid_to_uid_star
|
||||
atf_add_test_case rule_uid_to_uid_gid
|
||||
atf_add_test_case rule_uid_to_uid_gid_optional_sgid
|
||||
atf_add_test_case rule_uid_to_uid_gid_mandatory_sgid
|
||||
atf_add_test_case rule_uid_to_uid_gid_excluded_sgid
|
||||
atf_add_test_case rules_uid_to_uid
|
||||
atf_add_test_case rules_uid_to_uid_with_spaces
|
||||
}
|
||||
Reference in New Issue
Block a user