mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
tests: add userns regression tests
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
This commit is contained in:
parent
ffd74aadb1
commit
0727da47b3
5 changed files with 192 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -295,6 +295,7 @@ tests/regression/apparmor/unix_fd_server
|
|||
tests/regression/apparmor/unix_socket
|
||||
tests/regression/apparmor/unix_socket_client
|
||||
tests/regression/apparmor/unlink
|
||||
tests/regression/apparmor/userns
|
||||
tests/regression/apparmor/uservars.inc
|
||||
tests/regression/apparmor/xattrs
|
||||
tests/regression/apparmor/xattrs_profile
|
||||
|
|
|
@ -142,6 +142,7 @@ SRC=access.c \
|
|||
unix_socket.c \
|
||||
unix_socket_client.c \
|
||||
unlink.c \
|
||||
userns.c \
|
||||
xattrs.c \
|
||||
xattrs_profile.c
|
||||
|
||||
|
@ -255,6 +256,7 @@ TESTS=aa_exec \
|
|||
unix_socket_unnamed \
|
||||
unix_socket_autobind \
|
||||
unlink\
|
||||
userns\
|
||||
xattrs\
|
||||
xattrs_profile\
|
||||
longpath \
|
||||
|
|
|
@ -309,6 +309,20 @@ sub gen_pivot_root($) {
|
|||
}
|
||||
}
|
||||
|
||||
sub gen_userns($) {
|
||||
my $rule = shift;
|
||||
my @rules = split (/:/, $rule);
|
||||
if (@rules == 2) {
|
||||
if ($rules[1] =~ /^ALL$/) {
|
||||
push (@{$output_rules{$hat}}, " userns,\n");
|
||||
} else {
|
||||
push (@{$output_rules{$hat}}, " userns $rules[1],\n");
|
||||
}
|
||||
} else {
|
||||
(!$nowarn) && print STDERR "Warning: invalid userns description '$rule', ignored\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub gen_file($) {
|
||||
my $rule = shift;
|
||||
my @rules = split (/:/, $rule);
|
||||
|
@ -450,6 +464,8 @@ sub gen_from_args() {
|
|||
gen_umount($rule);
|
||||
} elsif ($rule =~ /^pivot_root:/) {
|
||||
gen_pivot_root($rule);
|
||||
} elsif ($rule =~ /^userns:/) {
|
||||
gen_userns($rule)
|
||||
} elsif ($rule =~ /^flag:/) {
|
||||
gen_flag($rule);
|
||||
} elsif ($rule =~ /^hat:/) {
|
||||
|
|
59
tests/regression/apparmor/userns.c
Normal file
59
tests/regression/apparmor/userns.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Canonical, Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int child(void *arg)
|
||||
{
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#define STACK_SIZE (1024 * 1024)
|
||||
static char child_stack[STACK_SIZE];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pid_t child_pid;
|
||||
int child_exit;
|
||||
|
||||
child_pid = clone(child, child_stack + STACK_SIZE,
|
||||
CLONE_NEWUSER | SIGCHLD, NULL);
|
||||
if (child_pid == -1) {
|
||||
perror("FAIL - clone");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (waitpid(child_pid, &child_exit, 0) == -1) {
|
||||
perror("FAIL - waitpid");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (WIFEXITED(child_exit)) {
|
||||
if (WEXITSTATUS(child_exit) != EXIT_SUCCESS) {
|
||||
fprintf(stderr, "FAIL - child ended with failure %d\n", child_exit);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
114
tests/regression/apparmor/userns.sh
Executable file
114
tests/regression/apparmor/userns.sh
Executable file
|
@ -0,0 +1,114 @@
|
|||
#! /bin/bash
|
||||
#Copyright (C) 2022 Canonical, Ltd.
|
||||
#
|
||||
#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, version 2 of the
|
||||
#License.
|
||||
|
||||
#=NAME userns
|
||||
#=DESCRIPTION
|
||||
# This test verifies if mediation of user namespaces is working
|
||||
#=END
|
||||
|
||||
pwd=`dirname $0`
|
||||
pwd=`cd $pwd ; /bin/pwd`
|
||||
|
||||
bin=$pwd
|
||||
|
||||
. $bin/prologue.inc
|
||||
|
||||
requires_kernel_features namespaces/mask/userns_create
|
||||
requires_parser_support "userns,"
|
||||
|
||||
apparmor_restrict_unprivileged_userns_path=/proc/sys/kernel/apparmor_restrict_unprivileged_userns
|
||||
if [ ! -e $apparmor_restrict_unprivileged_userns_path ]; then
|
||||
echo "$apparmor_restrict_unprivileged_userns_path not available. Skipping tests ..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
apparmor_restrict_unprivileged_userns=$(cat $apparmor_restrict_unprivileged_userns_path)
|
||||
|
||||
unprivileged_userns_clone_path=/proc/sys/kernel/unprivileged_userns_clone
|
||||
if [ -e $unprivileged_userns_clone_path ]; then
|
||||
unprivileged_userns_clone=$(cat $unprivileged_userns_clone_path)
|
||||
fi
|
||||
|
||||
restore_userns()
|
||||
{
|
||||
echo $apparmor_restrict_unprivileged_userns > $apparmor_restrict_unprivileged_userns_path
|
||||
}
|
||||
do_onexit="restore_userns"
|
||||
|
||||
do_test()
|
||||
{
|
||||
local desc="USERNS ($1)"
|
||||
expect_root=$2
|
||||
expect_user=$3
|
||||
generate_profile=$4
|
||||
|
||||
settest userns
|
||||
$generate_profile # settest removes the profile, so load it here
|
||||
runchecktest "$desc - root" $expect_root
|
||||
|
||||
settest -u "foo" userns # run tests as user foo
|
||||
$generate_profile # settest removes the profile, so load it here
|
||||
runchecktest "$desc - user" $expect_user
|
||||
}
|
||||
|
||||
if [ $unprivileged_userns_clone -eq 0 ]; then
|
||||
echo "WARN: unprivileged_userns_clone is enabled. Both confined and unconfined unprivileged user namespaces are not allowed"
|
||||
|
||||
detail="unprivileged_userns_clone disabled"
|
||||
do_test "unconfined - $detail" pass fail
|
||||
|
||||
generate_profile="genprofile userns cap:sys_admin"
|
||||
do_test "confined all perms $detail" pass fail "$generate_profile"
|
||||
|
||||
generate_profile="genprofile cap:sys_admin"
|
||||
do_test "confined no perms $detail" fail fail "$generate_profile"
|
||||
|
||||
generate_profile="genprofile userns:create cap:sys_admin"
|
||||
do_test "confined specific perms $detail" pass fail "$generate_profile"
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# confined tests should have the same results if apparmor_restrict_unprivileged_userns is enabled or not
|
||||
run_confined_tests()
|
||||
{
|
||||
generate_profile="genprofile userns"
|
||||
do_test "confined all perms $1" pass pass "$generate_profile"
|
||||
|
||||
generate_profile="genprofile"
|
||||
do_test "confined no perms $1" fail fail "$generate_profile"
|
||||
|
||||
generate_profile="genprofile userns:create"
|
||||
do_test "confined specific perms $1" pass pass "$generate_profile"
|
||||
}
|
||||
|
||||
# ----------------------------------------------------
|
||||
# disable restrictions on unprivileged user namespaces
|
||||
echo 0 > $apparmor_restrict_unprivileged_userns_path
|
||||
|
||||
detail="apparmor_restrict_unprivileged_userns disabled"
|
||||
do_test "unconfined - $detail" pass pass
|
||||
|
||||
run_confined_tests "$detail"
|
||||
|
||||
# ----------------------------------------------------
|
||||
# enable restrictions on unprivileged user namespaces
|
||||
echo 1 > $apparmor_restrict_unprivileged_userns_path
|
||||
|
||||
detail="apparmor_restrict_unprivileged_userns enabled"
|
||||
# user cannot create user namespace unless cap_sys_admin
|
||||
do_test "unconfined $detail" pass fail
|
||||
|
||||
# it should work when running as user with cap_sys_admin
|
||||
setcap cap_sys_admin+pie $bin/userns
|
||||
do_test "unconfined cap_sys_admin $detail" pass pass
|
||||
# remove cap_sys_admin from binary
|
||||
setcap cap_sys_admin= $bin/userns
|
||||
|
||||
run_confined_tests "$detail"
|
Loading…
Add table
Reference in a new issue