Add memory/filesystem tests

Add one memory test and one filesystem test
  memory/memfd_create
  filesystem/ext4/freeze-protection-bypass

Signed-off-by: xiawu <xiawu@redhat.com>
This commit is contained in:
xiawu 2018-08-29 05:02:24 +00:00 committed by Jeremy Cline
parent 8242e01fff
commit 64591e70e6
No known key found for this signature in database
GPG Key ID: 9223308FA9B246DB
13 changed files with 512 additions and 0 deletions

42
tests/filesystem.yml Normal file
View File

@ -0,0 +1,42 @@
---
# Tests suitable to run in a classic environment
- hosts: localhost
tags:
- classic
roles:
- role: standard-test-beakerlib
tests:
- filesystem/ext4/freeze-protection-bypass
required_packages:
- kernel
- e2fsprogs
- util-linux
ignore_errors: yes
# Tests suitable to run in a docker environment
- hosts: localhost
tags:
- container
roles:
- role: standard-test-beakerlib
tests:
- filesystem/ext4/freeze-protection-bypass
required_packages:
- kernel
- e2fsprogs
- util-linux
ignore_errors: yes
# Tests suitable to run in an Atomic Host environment
- hosts: localhost
tags:
- atomic
roles:
- role: standard-test-beakerlib
tests:
- filesystem/ext4/freeze-protection-bypass
required_packages:
- kernel
- e2fsprogs
- util-linux
ignore_errors: yes

View File

@ -0,0 +1,56 @@
# Copyright (c) 2018 Red Hat, 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 <http://www.gnu.org/licenses/>.
#
# Author: Boyang Xue <bxue@redhat.com>
TOPLEVEL_NAMESPACE=
PACKAGE_NAME=kernel
export TEST=freeze-protection-bypass
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
chmod a+x ./runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Boyang Xue <bxue@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Test for Bug - ext4: fix freeze protection bypass" >> $(METADATA)
@echo "Type: Regression" >> $(METADATA)
@echo "TestTime: 3m" >> $(METADATA)
@echo "RunFor: kernel" >> $(METADATA)
@echo "Requires: " >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2+" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -0,0 +1,5 @@
Test Name: freeze-protection-bypass
Author: Boyang Xue <bxue@redhat.com>
Location: /kernel/filesystem/freeze-protection-bypass
Description: regression test for Bug - ext4: fix freeze protection bypass

View File

@ -0,0 +1,86 @@
#!/bin/bash
#
# Copyright (c) 2018 Red Hat, 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 <http://www.gnu.org/licenses/>.
#
# Author: Boyang Xue <bxue@redhat.com>
PACKAGE=kernel
. /usr/share/beakerlib/beakerlib.sh
rlJournalStart
WDIR=/tmp/TC_freeze-protection-bypass.tmp.workdir
ODIR=/tmp/TC_freeze-protection-bypass.tmp.oldmnt
NDIR=/tmp/TC_freeze-protection-bypass.tmp.newmnt
mkdir $ODIR $NDIR $WDIR
cd $WDIR
fallocate -l 64M 64M.img
mkfs.ext4 -qF 64M.img
TDEV=$(losetup -f --show 64M.img)
TRID=$RANDOM
rlPhaseStartSetup
# The following patch for this bug is integrated in kernel v4.18
#
# vfs: add the sb_start_intwrite_trylock() helper
# ext4: factor out helper ext4_sample_last_mounted()
# ext4: do not update s_last_mounted of a frozen fs
KNVR=$(uname -r | cut -d '-' -f1)
rlCmpVersion $KNVR 4.18.0 >/dev/null
if [[ $? -eq 2 ]]; then
ISFIXED=0
rlPass "Kernel version < 4.18, indicating it's vulnerable to this bug. Test skipped as pass."
exit 0
else
ISFIXED=1
fi
rlRun "mount $TDEV $ODIR"
rlRun "echo TC_freeze-protection-bypass > $ODIR/TC_freeze-protection-bypass"
rlRun "umount $ODIR"
rlPhaseEnd
rlPhaseStartTest
rlRun "echo \"run TC_freeze-protection-bypass#${TRID}\" >/dev/kmsg"
rlRun "mount $TDEV $NDIR"
rlLog "Run 'fsfreeze -f $NDIR &'"
fsfreeze -f $NDIR &
wait $!
rlRun "grep TC_freeze-protection-bypass $NDIR/TC_freeze-protection-bypass"
rlRun "! dmesg | tac | sed -ne \"0,\#run TC_freeze-protection-bypass\#${TRID}#p\" | tac | grep -E \"ext4_journal_check_start|ext4_journal_start_sb\""
if [[ $? -eq 0 ]]; then
rlPass "The kernel warning isn't triggered. Test passes."
else
rlFail "The kernel warning is triggered. Test fails."
fi
rlPhaseEnd
rlPhaseStartCleanup
rlRun "fsfreeze -u $NDIR"
rlRun "umount $TDEV"
rlRun "losetup -d $TDEV"
rlRun "rm -f 64M.img"
rlRun "rm -rf $NDIR"
rlRun "rm -rf $ODIR"
rlRun "rm -rf $WDIR"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -0,0 +1,3 @@
#!/bin/bash
export TEST_DOCKER_EXTRA_ARGS="--privileged -v /dev:/dev"
exec merge-standard-inventory "$@"

15
tests/memory.yml Normal file
View File

@ -0,0 +1,15 @@
---
# Tests suitable to run in a classic environment
- hosts: localhost
tags:
- classic
roles:
- role: standard-test-beakerlib
tests:
- memory/memfd_create
required_packages:
- gcc
- libgcc
- glibc-devel
- glibc-static
ignore_errors: yes

View File

@ -0,0 +1,70 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Description: memfd_create test
# Author: Shu Wang <shuwang@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2016 Red Hat, 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 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 http://www.gnu.org/licenses/.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TENV=_env
ifeq ($(PKG_TOP_DIR),)
export PKG_TOP_DIR := $(shell p=$$PWD; while :; do \
[ -e $$p/env.mk -o -z "$$p" ] && { echo $$p; break; }; p=$${p%/*}; done)
export _TOP_DIR := $(shell p=$$PWD; while :; do \
[ -d $$p/.git -o -z "$$p" ] && { echo $$p; break; }; p=$${p%/*}; done)
-include $(PKG_TOP_DIR)/env.mk
endif
include $(TENV)
ifeq ($(_TOP_DIR),)
_TOP_DIR=/mnt/tests/$(TOPLEVEL_NAMESPACE)
endif
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE _env t_get_seals.c t_memfd_create.c
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Shu Wang <shuwang@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Test for memfd_create syscall." >> $(METADATA)
@echo "Type: Function" >> $(METADATA)
@echo "TestTime: 20m" >> $(METADATA)
@echo "RunFor: kernel" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2+" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -0,0 +1,3 @@
PURPOSE:
Description: tests for memfd_create syscall.
Author: Shu Wang <shuwang@redhat.com>

View File

@ -0,0 +1,8 @@
#This file was generated automatically,do not manually change it.
export TOPLEVEL_NAMESPACE=kernel
export PKG_NAMESPACE=kernel/general
export RELATIVE_PATH=memory/function/memfd_create
export PACKAGE=general
export PACKAGE_NAME=general
export PKG_LIST=
export TEST=/kernel/general/memory/function/memfd_create

View File

@ -0,0 +1,54 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Description: memfd_create test
# Author: Shu Wang <shuwang@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2016 Red Hat, 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 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 http://www.gnu.org/licenses/.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
gcc t_memfd_create.c -o t_memfd_create &&
gcc t_get_seals.c -o t_get_seals
if [ $? != 0 ]; then
rlLog "memfd_create is not supported."
report_result Test_Skipped PASS 99
exit 0
fi
function sanity_memfd_create()
{
rlRun "./t_memfd_create memf 1024 gswS &"
rlRun "./t_get_seals /proc/$!/fd/3 > seals"
rlRun "cat ./seals"
rlAssertGrep "SEAL GROW WRITE SHRINK" ./seals
rlRun "pkill t_memfd_create"
}
rlJournalStart
rlPhaseStartTest "sanity"
sanity_memfd_create
rlPhaseEnd
rlJournalEnd
rlJournalPrintText

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2016 Red Hat, 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 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 http://www.gnu.org/licenses/.
*
*/
#include <linux/fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int main(int argc, char *argv[])
{
int fd;
unsigned int seals;
if (argc != 2) {
fprintf(stderr, "%s /proc/PID/fd/FD\n", argv[0]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDWR);
if (fd == -1)
errExit("open");
seals = fcntl(fd, F_GET_SEALS);
if (seals == -1)
errExit("fcntl");
printf("Existing seals:");
if (seals & F_SEAL_SEAL)
printf(" SEAL");
if (seals & F_SEAL_GROW)
printf(" GROW");
if (seals & F_SEAL_WRITE)
printf(" WRITE");
if (seals & F_SEAL_SHRINK)
printf(" SHRINK");
printf("\n");
/* Code to map the file and access the contents of the
resulting mapping omitted */
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2016 Red Hat, 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 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 http://www.gnu.org/licenses/.
*
*/
#include <linux/memfd.h>
#include <linux/fcntl.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int main(int argc, char *argv[])
{
int fd;
unsigned int seals;
char *addr;
char *name, *seals_arg;
ssize_t len;
char* message = "this is a test message for memfd\n";
if (argc < 3) {
fprintf(stderr, "%s name size [seals]\n", argv[0]);
fprintf(stderr, "\t'seals' can contain any of the "
"following characters:\n");
fprintf(stderr, "\t\tg - F_SEAL_GROW\n");
fprintf(stderr, "\t\ts - F_SEAL_SHRINK\n");
fprintf(stderr, "\t\tw - F_SEAL_WRITE\n");
fprintf(stderr, "\t\tS - F_SEAL_SEAL\n");
exit(EXIT_FAILURE);
}
name = argv[1];
len = atoi(argv[2]);
seals_arg = argv[3];
/* Create an anonymous file in tmpfs; allow seals to be
placed on the file */
fd = syscall(SYS_memfd_create, name, MFD_ALLOW_SEALING);
if (fd == -1)
errExit("memfd_create");
/* Size the file as specified on the command line */
if (ftruncate(fd, len) == -1)
errExit("truncate");
if (write(fd, message, strlen(message)) <= 0)
errExit("write");
//printf("PID: %ld; fd: %d; /proc/%ld/fd/%d\n",
// (long) getpid(), fd, (long) getpid(), fd);
printf("/proc/%ld/fd/%d\n", (long) getpid(), fd);
/* Code to map the file and populate the mapping with data
omitted */
/* If a 'seals' command-line argument was supplied, set some
seals on the file */
if (seals_arg != NULL) {
seals = 0;
if (strchr(seals_arg, 'g') != NULL)
seals |= F_SEAL_GROW;
if (strchr(seals_arg, 's') != NULL)
seals |= F_SEAL_SHRINK;
if (strchr(seals_arg, 'w') != NULL)
seals |= F_SEAL_WRITE;
if (strchr(seals_arg, 'S') != NULL)
seals |= F_SEAL_SEAL;
if (fcntl(fd, F_ADD_SEALS, seals) == -1)
errExit("fcntl");
}
/* Keep running, so that the file created by memfd_create()
continues to exist */
pause();
exit(EXIT_SUCCESS);
}

6
tests/tests.yml Normal file
View File

@ -0,0 +1,6 @@
---
- name: memory test
import_playbook: memory.yml
- name: filesystem test
import_playbook: filesystem.yml