aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-04-03 20:31:09 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-04-03 20:31:09 +0000
commit064dfbd71a25175559657ca7bf85224be6840ef5 (patch)
tree21df5650189a18b6e92f11a618bac3deb1adf361
parent287a2a948c05dc2bdbc52ab0ce090b2e324c6d8c (diff)
parentcdb9cd95d819b7d394f63db8dd87804de5aa3e69 (diff)
downloadltp-android14-tests-release.tar.gz
Snap for 11666499 from cdb9cd95d819b7d394f63db8dd87804de5aa3e69 to android14-tests-releaseandroid14-tests-release
Change-Id: I85b19974289ff82a6568e1771c64365c6c34b37c
-rw-r--r--.github/workflows/ci.yml3
-rw-r--r--.github/workflows/wiki-mirror.yml16
-rw-r--r--.gitignore21
-rw-r--r--Android.bp14
-rw-r--r--Makefile1
-rw-r--r--Makefile.release46
-rw-r--r--README.md3
-rw-r--r--VERSION2
-rw-r--r--android/Android.ltp.mk8
-rw-r--r--android/README.md8
-rw-r--r--android/include/config.h3
-rw-r--r--android/ltp_package_list.mk55
-rw-r--r--android/tools/android_build_generator.py2
-rwxr-xr-xandroid/tools/compare_ltp_projects.py33
-rw-r--r--android/tools/disabled_libs.txt2
-rw-r--r--android/tools/disabled_tests.txt7
-rwxr-xr-x[-rw-r--r--]android/tools/make_install_parser.py1
-rwxr-xr-x[-rw-r--r--]android/tools/make_parser.py32
-rwxr-xr-xci/debian.minimal.sh3
-rw-r--r--configure.ac11
-rw-r--r--doc/Build-System.rest (renamed from doc/build-system-guide.txt)2
-rw-r--r--doc/C-Test-API.asciidoc (renamed from doc/c-test-api.txt)80
-rw-r--r--doc/C-Test-Case-Tutorial.asciidoc (renamed from doc/c-test-tutorial-simple.txt)4
-rw-r--r--doc/C-Test-Network-API.asciidoc (renamed from doc/network-c-api.txt)0
-rw-r--r--doc/KVM-Test-API.asciidoc (renamed from doc/kvm-test-api.txt)109
-rw-r--r--doc/LTP-Library-API-Writing-Guidelines.asciidoc (renamed from doc/library-api-writing-guidelines.txt)0
-rw-r--r--doc/LTP-Release-Procedure.asciidoc170
-rw-r--r--doc/Maintainer-Patch-Review-Checklist.asciidoc141
-rw-r--r--doc/Shell-Test-API.asciidoc (renamed from doc/shell-test-api.txt)15
-rw-r--r--doc/Supported-kernel,-libc,-toolchain-versions.asciidoc (renamed from doc/supported-kernel-libc-versions.txt)2
-rw-r--r--doc/Test-Writing-Guidelines.asciidoc (renamed from doc/test-writing-guidelines.txt)4
-rw-r--r--doc/User-Guidelines.asciidoc (renamed from doc/user-guide.txt)0
-rw-r--r--doc/maintainer-patch-review-checklist.txt60
-rw-r--r--doc/man1/ltp-pan.12
-rw-r--r--doc/man3/parse_ranges.32
-rw-r--r--doc/namespaces-helper-tools.txt16
-rw-r--r--docparse/README.md2
-rwxr-xr-xdocparse/testinfo.pl3
-rwxr-xr-xexecltp.in474
-rw-r--r--gen.bp513
-rw-r--r--include/ipcshm.h54
-rw-r--r--include/lapi/faccessat.h22
-rw-r--r--include/lapi/fcntl.h37
-rw-r--r--include/lapi/fs.h21
-rw-r--r--include/lapi/ioprio.h47
-rw-r--r--include/lapi/mmap.h5
-rw-r--r--include/lapi/mount.h4
-rw-r--r--include/lapi/sched.h19
-rw-r--r--include/lapi/sem.h4
-rw-r--r--include/lapi/stat.h56
-rw-r--r--include/lapi/syscalls/aarch64.in1
-rw-r--r--include/lapi/syscalls/arc.in1
-rw-r--r--include/lapi/syscalls/arm.in1
-rw-r--r--include/lapi/syscalls/hppa.in1
-rw-r--r--include/lapi/syscalls/i386.in1
-rw-r--r--include/lapi/syscalls/ia64.in1
-rw-r--r--include/lapi/syscalls/loongarch.in307
-rw-r--r--include/lapi/syscalls/order1
-rw-r--r--include/lapi/syscalls/powerpc.in1
-rw-r--r--include/lapi/syscalls/powerpc64.in1
-rw-r--r--include/lapi/syscalls/s390.in1
-rw-r--r--include/lapi/syscalls/s390x.in1
-rw-r--r--include/lapi/syscalls/sh.in1
-rw-r--r--include/lapi/syscalls/sparc.in1
-rw-r--r--include/lapi/syscalls/sparc64.in1
-rw-r--r--include/lapi/syscalls/x86_64.in1
-rw-r--r--include/libnewipc.h2
-rw-r--r--include/mk/automake.mk3
-rw-r--r--include/safe_net_fn.h3
-rw-r--r--include/tst_buffers.h11
-rw-r--r--include/tst_cgroup.h4
-rw-r--r--include/tst_clone.h1
-rw-r--r--include/tst_kernel.h14
-rw-r--r--include/tst_memutils.h5
-rw-r--r--include/tst_minmax.h3
-rw-r--r--include/tst_netdevice.h124
-rw-r--r--include/tst_pid.h8
-rw-r--r--include/tst_safe_net.h3
-rw-r--r--include/tst_safe_posix_ipc.h2
-rw-r--r--include/tst_safe_pthread.h52
-rw-r--r--include/tst_test.h7
-rw-r--r--include/tst_test_macros.h39
-rw-r--r--lib/.gitignore3
-rw-r--r--lib/Makefile13
-rwxr-xr-xlib/gen_version.sh16
-rw-r--r--lib/newlib_tests/Makefile2
-rw-r--r--lib/random_range.c2
-rw-r--r--lib/safe_file_ops.c18
-rw-r--r--lib/safe_macros.c17
-rw-r--r--lib/safe_net.c17
-rw-r--r--lib/safe_pthread.c161
-rw-r--r--lib/tests/.gitignore17
-rw-r--r--lib/tests/tst_tmpdir_test.c2
-rw-r--r--lib/tlibio.c14
-rw-r--r--lib/tst_bool_expr.c2
-rw-r--r--lib/tst_buffers.c28
-rw-r--r--lib/tst_cgroup.c90
-rw-r--r--lib/tst_clocks.c3
-rw-r--r--lib/tst_clone.c1
-rw-r--r--lib/tst_fill_fs.c22
-rw-r--r--lib/tst_fs_setup.c6
-rw-r--r--lib/tst_hugepage.c1
-rw-r--r--lib/tst_kernel.c39
-rw-r--r--lib/tst_kvercmp.c4
-rw-r--r--lib/tst_lockdown.c41
-rw-r--r--lib/tst_memutils.c9
-rw-r--r--lib/tst_netdevice.c213
-rw-r--r--lib/tst_pid.c46
-rw-r--r--lib/tst_test.c106
-rw-r--r--lib/tst_timer_test.c2
-rw-r--r--libs/libltpnuma/tst_numa.c6
-rwxr-xr-xmetadata/parse.sh2
-rw-r--r--runtest/containers30
-rw-r--r--runtest/controllers1
-rw-r--r--runtest/cve32
-rw-r--r--runtest/hugetlb1
-rw-r--r--runtest/ipc2
-rw-r--r--runtest/kvm3
-rw-r--r--runtest/net.nfs13
-rw-r--r--runtest/sched1
-rw-r--r--runtest/staging1
-rw-r--r--runtest/syscalls41
-rw-r--r--runtest/syscalls-ipc2
-rwxr-xr-xtestcases/commands/df/df01.sh7
-rwxr-xr-xtestcases/commands/eject/eject-tests.sh2
-rw-r--r--testcases/commands/file/datafiles/in.csh4
-rw-r--r--testcases/commands/file/datafiles/in.ksh4
-rwxr-xr-xtestcases/commands/file/file01.sh35
-rwxr-xr-xtestcases/commands/insmod/insmod01.sh3
-rw-r--r--testcases/cve/.gitignore1
-rw-r--r--testcases/cve/cve-2015-3290.c3
-rw-r--r--testcases/cve/cve-2016-10044.c6
-rw-r--r--testcases/cve/stack_clash.c89
-rw-r--r--testcases/cve/tcindex01.c136
-rwxr-xr-xtestcases/kernel/connectors/pec/cn_pec.sh4
-rw-r--r--testcases/kernel/connectors/pec/pec_listener.c4
-rw-r--r--testcases/kernel/containers/.gitignore14
-rw-r--r--testcases/kernel/containers/Makefile27
-rw-r--r--testcases/kernel/containers/Makefile.inc45
-rw-r--r--testcases/kernel/containers/README50
-rw-r--r--testcases/kernel/containers/TEST_PLAN.txt27
-rw-r--r--testcases/kernel/containers/libclone/Makefile27
-rw-r--r--testcases/kernel/containers/libclone/libclone.c142
-rw-r--r--testcases/kernel/containers/libclone/libclone.h81
-rw-r--r--testcases/kernel/containers/mountns/.gitignore4
-rw-r--r--testcases/kernel/containers/mountns/mountns.h18
-rw-r--r--testcases/kernel/containers/mountns/mountns01.c23
-rw-r--r--testcases/kernel/containers/mountns/mountns02.c23
-rw-r--r--testcases/kernel/containers/mountns/mountns03.c23
-rw-r--r--testcases/kernel/containers/mountns/mountns04.c6
-rw-r--r--testcases/kernel/containers/mqns/Makefile27
-rw-r--r--testcases/kernel/containers/mqns/mqns.h11
-rw-r--r--testcases/kernel/containers/mqns/mqns_01.c188
-rw-r--r--testcases/kernel/containers/mqns/mqns_02.c248
-rw-r--r--testcases/kernel/containers/mqns/mqns_03.c305
-rw-r--r--testcases/kernel/containers/mqns/mqns_04.c274
-rw-r--r--testcases/kernel/containers/mqns/mqns_helper.h53
-rw-r--r--testcases/kernel/containers/netns/Makefile4
-rwxr-xr-xtestcases/kernel/containers/netns/netns_lib.sh25
-rwxr-xr-xtestcases/kernel/containers/netns/netns_sysfs.sh18
-rw-r--r--testcases/kernel/containers/pidns/Makefile3
-rw-r--r--testcases/kernel/containers/pidns/pidns01.c31
-rw-r--r--testcases/kernel/containers/pidns/pidns02.c36
-rw-r--r--testcases/kernel/containers/pidns/pidns03.c21
-rw-r--r--testcases/kernel/containers/pidns/pidns04.c174
-rw-r--r--testcases/kernel/containers/pidns/pidns05.c298
-rw-r--r--testcases/kernel/containers/pidns/pidns06.c151
-rw-r--r--testcases/kernel/containers/pidns/pidns10.c133
-rw-r--r--testcases/kernel/containers/pidns/pidns12.c29
-rw-r--r--testcases/kernel/containers/pidns/pidns13.c9
-rw-r--r--testcases/kernel/containers/pidns/pidns16.c192
-rw-r--r--testcases/kernel/containers/pidns/pidns17.c190
-rw-r--r--testcases/kernel/containers/pidns/pidns20.c35
-rw-r--r--testcases/kernel/containers/pidns/pidns30.c325
-rw-r--r--testcases/kernel/containers/pidns/pidns31.c360
-rw-r--r--testcases/kernel/containers/pidns/pidns32.c54
-rw-r--r--testcases/kernel/containers/pidns/pidns_helper.h34
-rw-r--r--testcases/kernel/containers/share/.gitignore4
-rw-r--r--testcases/kernel/containers/share/Makefile22
-rw-r--r--testcases/kernel/containers/share/ns_create.c108
-rw-r--r--testcases/kernel/containers/share/ns_exec.c157
-rw-r--r--testcases/kernel/containers/share/ns_ifmove.c134
-rw-r--r--testcases/kernel/containers/share/setns_check.c32
-rw-r--r--testcases/kernel/containers/sysvipc/common.h50
-rw-r--r--testcases/kernel/containers/sysvipc/mesgq_nstest.c13
-rw-r--r--testcases/kernel/containers/sysvipc/msg_comm.c19
-rw-r--r--testcases/kernel/containers/sysvipc/sem_comm.c19
-rw-r--r--testcases/kernel/containers/sysvipc/sem_nstest.c12
-rw-r--r--testcases/kernel/containers/sysvipc/semtest_2ns.c15
-rw-r--r--testcases/kernel/containers/sysvipc/shm_comm.c19
-rw-r--r--testcases/kernel/containers/sysvipc/shmem_2nstest.c15
-rw-r--r--testcases/kernel/containers/sysvipc/shmnstest.c10
-rw-r--r--testcases/kernel/containers/userns/.gitignore9
-rw-r--r--testcases/kernel/containers/userns/Makefile23
-rw-r--r--testcases/kernel/containers/userns/common.h20
-rw-r--r--testcases/kernel/containers/userns/userns01.c32
-rw-r--r--testcases/kernel/containers/userns/userns02.c34
-rw-r--r--testcases/kernel/containers/userns/userns03.c73
-rw-r--r--testcases/kernel/containers/userns/userns04.c48
-rw-r--r--testcases/kernel/containers/userns/userns05.c51
-rw-r--r--testcases/kernel/containers/userns/userns06.c44
-rw-r--r--testcases/kernel/containers/userns/userns06_capcheck.c19
-rw-r--r--testcases/kernel/containers/userns/userns07.c63
-rw-r--r--testcases/kernel/containers/userns/userns08.c5
-rw-r--r--testcases/kernel/containers/userns/userns_helper.h59
-rw-r--r--testcases/kernel/containers/utsname/.gitignore5
-rw-r--r--testcases/kernel/containers/utsname/Makefile25
-rwxr-xr-xtestcases/kernel/containers/utsname/runutstests_noltp.sh41
-rw-r--r--testcases/kernel/containers/utsname/utsname01.c56
-rw-r--r--testcases/kernel/containers/utsname/utsname02.c81
-rw-r--r--testcases/kernel/containers/utsname/utsname03.c121
-rw-r--r--testcases/kernel/containers/utsname/utsname04.c63
-rw-r--r--testcases/kernel/containers/utsname/utstest.c353
-rw-r--r--testcases/kernel/controllers/cgroup/.gitignore1
-rw-r--r--testcases/kernel/controllers/cgroup/cgroup_core03.c131
-rwxr-xr-xtestcases/kernel/controllers/cgroup_fj/cgroup_fj_stress.sh4
-rwxr-xr-xtestcases/kernel/controllers/cpuctl/run_cpuctl_stress_test.sh6
-rwxr-xr-xtestcases/kernel/controllers/cpuctl/run_cpuctl_test.sh6
-rwxr-xr-xtestcases/kernel/controllers/cpuctl_fj/run_cpuctl_test_fj.sh2
-rwxr-xr-xtestcases/kernel/controllers/cpuset/cpuset_funcs.sh2
-rwxr-xr-xtestcases/kernel/controllers/cpuset/cpuset_memory_pressure_test/cpuset_memory_pressure_testset.sh6
-rwxr-xr-xtestcases/kernel/controllers/cpuset/cpuset_memory_spread_test/cpuset_memory_spread_testset.sh10
-rwxr-xr-xtestcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_testset.sh2
-rwxr-xr-xtestcases/kernel/controllers/cpuset/cpuset_regression_test.sh9
-rw-r--r--testcases/kernel/controllers/freezer/00_description.txt2
-rwxr-xr-xtestcases/kernel/controllers/freezer/freeze_self_thaw.sh2
-rwxr-xr-xtestcases/kernel/controllers/freezer/vfork_freeze.sh2
-rw-r--r--testcases/kernel/controllers/io/io_control01.c1
-rwxr-xr-xtestcases/kernel/controllers/memcg/functional/memcg_failcnt.sh4
-rwxr-xr-xtestcases/kernel/controllers/memcg/functional/memcg_lib.sh4
-rwxr-xr-xtestcases/kernel/controllers/memcg/stress/memcg_stress_test.sh19
-rw-r--r--testcases/kernel/crypto/pcrypt_aead01.c4
-rw-r--r--testcases/kernel/device-drivers/nls/README2
-rwxr-xr-xtestcases/kernel/device-drivers/zram/zram01.sh27
-rw-r--r--testcases/kernel/fs/doio/write_log.c22
-rw-r--r--testcases/kernel/fs/fs_bind/fs_bind_lib.sh7
-rw-r--r--testcases/kernel/fs/fs_fill/fs_fill.c9
-rw-r--r--testcases/kernel/fs/fsstress/fsstress.c3
-rw-r--r--testcases/kernel/fs/fsstress/global.h9
-rw-r--r--testcases/kernel/fs/lftest/lftest.c2
-rw-r--r--testcases/kernel/fs/read_all/Makefile1
-rw-r--r--testcases/kernel/fs/scsi/ltpscsi/scsimain.c5
-rw-r--r--testcases/kernel/io/direct_io/diotest3.c2
-rw-r--r--testcases/kernel/io/direct_io/diotest4.c1
-rw-r--r--testcases/kernel/io/direct_io/diotest6.c2
-rw-r--r--testcases/kernel/io/ltp-aiodio/aiocp.c4
-rw-r--r--testcases/kernel/ipc/semaphore/.gitignore2
-rw-r--r--testcases/kernel/ipc/semaphore/Makefile30
-rw-r--r--testcases/kernel/ipc/semaphore/sem01.c164
-rw-r--r--testcases/kernel/kvm/.gitignore3
-rw-r--r--testcases/kernel/kvm/Makefile7
-rw-r--r--testcases/kernel/kvm/bootstrap_x86.S103
-rw-r--r--testcases/kernel/kvm/bootstrap_x86_64.S110
-rw-r--r--testcases/kernel/kvm/include/kvm_common.h8
-rw-r--r--testcases/kernel/kvm/include/kvm_guest.h14
-rw-r--r--testcases/kernel/kvm/include/kvm_host.h20
-rw-r--r--testcases/kernel/kvm/include/kvm_x86.h72
-rw-r--r--testcases/kernel/kvm/include/kvm_x86_svm.h166
-rw-r--r--testcases/kernel/kvm/kvm_svm01.c123
-rw-r--r--testcases/kernel/kvm/kvm_svm02.c152
-rw-r--r--testcases/kernel/kvm/kvm_svm03.c169
-rw-r--r--testcases/kernel/kvm/lib_guest.c18
-rw-r--r--testcases/kernel/kvm/lib_host.c55
-rw-r--r--testcases/kernel/kvm/lib_x86.c247
-rw-r--r--testcases/kernel/kvm/linker/x86.lds5
-rw-r--r--testcases/kernel/kvm/linker/x86_64.lds5
-rw-r--r--testcases/kernel/mem/.gitignore1
-rw-r--r--testcases/kernel/mem/hugetlb/hugemmap/Makefile1
-rw-r--r--testcases/kernel/mem/hugetlb/hugemmap/hugemmap15.c13
-rw-r--r--testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c9
-rw-r--r--testcases/kernel/mem/hugetlb/hugemmap/hugemmap32.c95
-rw-r--r--testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat04.c19
-rw-r--r--testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl01.c29
-rw-r--r--testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl02.c37
-rw-r--r--testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl03.c14
-rw-r--r--testcases/kernel/mem/hugetlb/hugeshmget/hugeshmget03.c2
-rw-r--r--testcases/kernel/mem/hugetlb/lib/hugetlb.h6
-rw-r--r--testcases/kernel/mem/include/mem.h1
-rw-r--r--testcases/kernel/mem/ksm/ksm05.c4
-rw-r--r--testcases/kernel/mem/lib/mem.c2
-rw-r--r--testcases/kernel/mem/oom/oom01.c17
-rw-r--r--testcases/kernel/mem/oom/oom02.c14
-rw-r--r--testcases/kernel/mem/oom/oom03.c14
-rw-r--r--testcases/kernel/mem/oom/oom04.c14
-rw-r--r--testcases/kernel/mem/oom/oom05.c14
-rw-r--r--testcases/kernel/mem/thp/thp03.c1
-rw-r--r--testcases/kernel/mem/thp/thp04.c2
-rw-r--r--testcases/kernel/mem/tunable/max_map_count.c27
-rw-r--r--testcases/kernel/mem/tunable/min_free_kbytes.c16
-rw-r--r--testcases/kernel/mem/tunable/overcommit_memory.c20
-rwxr-xr-xtestcases/kernel/mem/vma/vma05.sh1
-rwxr-xr-xtestcases/kernel/numa/numa01.sh2
-rw-r--r--testcases/kernel/numa/support_numa.c1
-rw-r--r--testcases/kernel/sched/cfs-scheduler/.gitignore3
-rw-r--r--testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c10
-rw-r--r--testcases/kernel/sched/cfs-scheduler/starvation.c113
-rw-r--r--testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c2
-rw-r--r--testcases/kernel/security/tomoyo/.gitignore9
-rw-r--r--testcases/kernel/security/tomoyo/Makefile29
-rw-r--r--testcases/kernel/security/tomoyo/README58
-rw-r--r--testcases/kernel/security/tomoyo/include.h379
-rw-r--r--testcases/kernel/security/tomoyo/newns.c49
-rw-r--r--testcases/kernel/security/tomoyo/testall.sh46
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_accept_test.c146
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_file_test.c304
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_filesystem_test.c633
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_new_file_test.c627
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_new_test.c652
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_policy_io_test.c195
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_policy_memory_test.c358
-rw-r--r--testcases/kernel/security/tomoyo/tomoyo_rewrite_test.c169
-rw-r--r--testcases/kernel/sound/snd_timer01.c2
-rw-r--r--testcases/kernel/syscalls/access/access01.c9
-rw-r--r--testcases/kernel/syscalls/access/access02.c22
-rw-r--r--testcases/kernel/syscalls/access/access03.c5
-rw-r--r--testcases/kernel/syscalls/access/access04.c71
-rw-r--r--testcases/kernel/syscalls/acct/acct01.c84
-rw-r--r--testcases/kernel/syscalls/adjtimex/adjtimex02.c13
-rw-r--r--testcases/kernel/syscalls/adjtimex/adjtimex03.c13
-rw-r--r--testcases/kernel/syscalls/alarm/alarm02.c1
-rw-r--r--testcases/kernel/syscalls/bind/bind03.c6
-rw-r--r--testcases/kernel/syscalls/bpf/bpf_common.h1
-rw-r--r--testcases/kernel/syscalls/bpf/bpf_prog01.c2
-rw-r--r--testcases/kernel/syscalls/bpf/bpf_prog02.c4
-rw-r--r--testcases/kernel/syscalls/bpf/bpf_prog04.c1
-rw-r--r--testcases/kernel/syscalls/bpf/bpf_prog05.c2
-rw-r--r--testcases/kernel/syscalls/bpf/bpf_prog06.c2
-rw-r--r--testcases/kernel/syscalls/bpf/bpf_prog07.c2
-rw-r--r--testcases/kernel/syscalls/capset/capset01.c18
-rw-r--r--testcases/kernel/syscalls/capset/capset02.c20
-rw-r--r--testcases/kernel/syscalls/capset/capset03.c10
-rw-r--r--testcases/kernel/syscalls/capset/capset04.c8
-rw-r--r--testcases/kernel/syscalls/chdir/chdir01.c55
-rw-r--r--testcases/kernel/syscalls/chmod/chmod01.c28
-rw-r--r--testcases/kernel/syscalls/chown/chown02.c1
-rw-r--r--testcases/kernel/syscalls/chroot/chroot03.c46
-rw-r--r--testcases/kernel/syscalls/clone/clone04.c5
-rw-r--r--testcases/kernel/syscalls/clone3/.gitignore1
-rw-r--r--testcases/kernel/syscalls/clone3/clone302.c5
-rw-r--r--testcases/kernel/syscalls/clone3/clone303.c94
-rw-r--r--testcases/kernel/syscalls/delete_module/delete_module01.c28
-rw-r--r--testcases/kernel/syscalls/delete_module/delete_module03.c3
-rw-r--r--testcases/kernel/syscalls/dup/dup01.c25
-rw-r--r--testcases/kernel/syscalls/dup/dup02.c34
-rw-r--r--testcases/kernel/syscalls/dup/dup03.c34
-rw-r--r--testcases/kernel/syscalls/dup/dup04.c44
-rw-r--r--testcases/kernel/syscalls/dup/dup05.c46
-rw-r--r--testcases/kernel/syscalls/epoll_ctl/epoll_ctl02.c4
-rw-r--r--testcases/kernel/syscalls/epoll_ctl/epoll_ctl03.c2
-rw-r--r--testcases/kernel/syscalls/epoll_ctl/epoll_ctl04.c4
-rw-r--r--testcases/kernel/syscalls/epoll_ctl/epoll_ctl05.c6
-rw-r--r--testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c2
-rw-r--r--testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c2
-rw-r--r--testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c2
-rw-r--r--testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c2
-rw-r--r--testcases/kernel/syscalls/epoll_pwait/epoll_pwait05.c2
-rw-r--r--testcases/kernel/syscalls/epoll_wait/.gitignore3
-rw-r--r--testcases/kernel/syscalls/epoll_wait/epoll_wait02.c2
-rw-r--r--testcases/kernel/syscalls/epoll_wait/epoll_wait03.c2
-rw-r--r--testcases/kernel/syscalls/epoll_wait/epoll_wait04.c2
-rw-r--r--testcases/kernel/syscalls/epoll_wait/epoll_wait05.c126
-rw-r--r--testcases/kernel/syscalls/epoll_wait/epoll_wait06.c107
-rw-r--r--testcases/kernel/syscalls/epoll_wait/epoll_wait07.c73
-rw-r--r--testcases/kernel/syscalls/eventfd/.gitignore5
-rw-r--r--testcases/kernel/syscalls/eventfd/eventfd01.c749
-rw-r--r--testcases/kernel/syscalls/eventfd/eventfd02.c53
-rw-r--r--testcases/kernel/syscalls/eventfd/eventfd03.c57
-rw-r--r--testcases/kernel/syscalls/eventfd/eventfd04.c60
-rw-r--r--testcases/kernel/syscalls/eventfd/eventfd05.c47
-rw-r--r--testcases/kernel/syscalls/eventfd/eventfd06.c174
-rw-r--r--testcases/kernel/syscalls/eventfd2/eventfd2.h18
-rw-r--r--testcases/kernel/syscalls/eventfd2/eventfd2_01.c148
-rw-r--r--testcases/kernel/syscalls/eventfd2/eventfd2_02.c147
-rw-r--r--testcases/kernel/syscalls/eventfd2/eventfd2_03.c128
-rw-r--r--testcases/kernel/syscalls/execve/execve01.c2
-rw-r--r--testcases/kernel/syscalls/execve/execve06.c2
-rw-r--r--testcases/kernel/syscalls/faccessat/.gitignore1
-rw-r--r--testcases/kernel/syscalls/faccessat/faccessat01.c203
-rw-r--r--testcases/kernel/syscalls/faccessat/faccessat02.c67
-rw-r--r--testcases/kernel/syscalls/faccessat2/.gitignore2
-rw-r--r--testcases/kernel/syscalls/faccessat2/Makefile9
-rw-r--r--testcases/kernel/syscalls/faccessat2/faccessat201.c88
-rw-r--r--testcases/kernel/syscalls/faccessat2/faccessat202.c102
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify.h21
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify13.c63
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify14.c198
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify22.c33
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify23.c8
-rw-r--r--testcases/kernel/syscalls/fchmod/fchmod02.c20
-rw-r--r--testcases/kernel/syscalls/fchmod/fchmod03.c9
-rw-r--r--testcases/kernel/syscalls/fchmod/fchmod04.c9
-rw-r--r--testcases/kernel/syscalls/fchown/fchown02.c1
-rw-r--r--testcases/kernel/syscalls/fcntl/.gitignore2
-rw-r--r--testcases/kernel/syscalls/fcntl/fcntl06.c165
-rw-r--r--testcases/kernel/syscalls/fcntl/fcntl11.c6
-rw-r--r--testcases/kernel/syscalls/fcntl/fcntl19.c6
-rw-r--r--testcases/kernel/syscalls/fcntl/fcntl20.c6
-rw-r--r--testcases/kernel/syscalls/fcntl/fcntl21.c6
-rw-r--r--testcases/kernel/syscalls/fcntl/fcntl30.c111
-rw-r--r--testcases/kernel/syscalls/fcntl/fcntl33.c2
-rw-r--r--testcases/kernel/syscalls/finit_module/finit_module01.c3
-rw-r--r--testcases/kernel/syscalls/finit_module/finit_module02.c10
-rw-r--r--testcases/kernel/syscalls/flistxattr/flistxattr01.c2
-rw-r--r--testcases/kernel/syscalls/fork/fork03.c144
-rw-r--r--testcases/kernel/syscalls/fsconfig/.gitignore1
-rw-r--r--testcases/kernel/syscalls/fsconfig/fsconfig03.c97
-rw-r--r--testcases/kernel/syscalls/futex/Makefile3
-rw-r--r--testcases/kernel/syscalls/futex/futex_wake04.c1
-rw-r--r--testcases/kernel/syscalls/getcpu/getcpu01.c5
-rw-r--r--testcases/kernel/syscalls/geteuid/geteuid01.c91
-rw-r--r--testcases/kernel/syscalls/geteuid/geteuid02.c89
-rw-r--r--testcases/kernel/syscalls/getgroups/getgroups01.c2
-rw-r--r--testcases/kernel/syscalls/gethostname/gethostname01.c166
-rw-r--r--testcases/kernel/syscalls/getpgid/getpgid01.c160
-rw-r--r--testcases/kernel/syscalls/getpgid/getpgid02.c143
-rw-r--r--testcases/kernel/syscalls/getpgrp/getpgrp01.c166
-rw-r--r--testcases/kernel/syscalls/getpid/getpid02.c1
-rw-r--r--testcases/kernel/syscalls/getrusage/getrusage04.c11
-rw-r--r--testcases/kernel/syscalls/init_module/init_module01.c3
-rw-r--r--testcases/kernel/syscalls/init_module/init_module02.c9
-rw-r--r--testcases/kernel/syscalls/io_uring/io_uring01.c5
-rw-r--r--testcases/kernel/syscalls/io_uring/io_uring02.c5
-rw-r--r--testcases/kernel/syscalls/ioctl/Makefile2
-rw-r--r--testcases/kernel/syscalls/ioctl/ioctl01.c84
-rwxr-xr-xtestcases/kernel/syscalls/ioctl/test_ioctl23
-rw-r--r--testcases/kernel/syscalls/ioprio/ioprio.h31
-rw-r--r--testcases/kernel/syscalls/ioprio/ioprio_get01.c9
-rw-r--r--testcases/kernel/syscalls/ioprio/ioprio_set01.c9
-rw-r--r--testcases/kernel/syscalls/ioprio/ioprio_set02.c9
-rw-r--r--testcases/kernel/syscalls/ioprio/ioprio_set03.c11
-rw-r--r--testcases/kernel/syscalls/ipc/msgctl/msgctl01.c2
-rw-r--r--testcases/kernel/syscalls/ipc/msgget/msgget02.c6
-rw-r--r--testcases/kernel/syscalls/ipc/msgstress/msgstress03.c7
-rw-r--r--testcases/kernel/syscalls/ipc/semget/.gitignore2
-rw-r--r--testcases/kernel/syscalls/ipc/semget/Makefile4
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget01.c187
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget02.c221
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget03.c133
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget05.c189
-rw-r--r--testcases/kernel/syscalls/ipc/semget/semget06.c143
-rw-r--r--testcases/kernel/syscalls/ipc/semop/.gitignore2
-rw-r--r--testcases/kernel/syscalls/ipc/semop/Makefile5
-rw-r--r--testcases/kernel/syscalls/ipc/semop/semop04.c93
-rw-r--r--testcases/kernel/syscalls/ipc/semop/semop05.c (renamed from testcases/kernel/ipc/semaphore/sem02.c)0
-rw-r--r--testcases/kernel/syscalls/ipc/shmget/shmget02.c28
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl02.c1
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl07.c2
-rw-r--r--testcases/kernel/syscalls/madvise/.gitignore1
-rw-r--r--testcases/kernel/syscalls/madvise/Makefile2
-rw-r--r--testcases/kernel/syscalls/madvise/madvise01.c1
-rw-r--r--testcases/kernel/syscalls/madvise/madvise02.c1
-rw-r--r--testcases/kernel/syscalls/madvise/madvise06.c10
-rw-r--r--testcases/kernel/syscalls/madvise/madvise11.c442
-rw-r--r--testcases/kernel/syscalls/memfd_create/memfd_create02.c4
-rw-r--r--testcases/kernel/syscalls/memfd_create/memfd_create04.c27
-rw-r--r--testcases/kernel/syscalls/mknod/mknod01.c137
-rw-r--r--testcases/kernel/syscalls/mknod/mknod02.c316
-rw-r--r--testcases/kernel/syscalls/mlock/mlock01.c159
-rw-r--r--testcases/kernel/syscalls/mlock/mlock02.c190
-rw-r--r--testcases/kernel/syscalls/mlock/mlock03.c131
-rw-r--r--testcases/kernel/syscalls/mlock/mlock04.c110
-rw-r--r--testcases/kernel/syscalls/mmap/.gitignore2
-rw-r--r--testcases/kernel/syscalls/mmap/mmap02.c204
-rw-r--r--testcases/kernel/syscalls/mmap/mmap05.c220
-rw-r--r--testcases/kernel/syscalls/mmap/mmap06.c176
-rw-r--r--testcases/kernel/syscalls/mmap/mmap07.c146
-rw-r--r--testcases/kernel/syscalls/mmap/mmap08.c155
-rw-r--r--testcases/kernel/syscalls/mmap/mmap17.c1
-rw-r--r--testcases/kernel/syscalls/mmap/mmap20.c64
-rw-r--r--testcases/kernel/syscalls/mount/.gitignore1
-rw-r--r--testcases/kernel/syscalls/mount/mount03.c2
-rw-r--r--testcases/kernel/syscalls/mount/mount07.c177
-rw-r--r--testcases/kernel/syscalls/mount_setattr/mount_setattr01.c1
-rw-r--r--testcases/kernel/syscalls/mprotect/.gitignore1
-rw-r--r--testcases/kernel/syscalls/mprotect/mprotect05.c69
-rw-r--r--testcases/kernel/syscalls/mq_notify/.gitignore1
-rw-r--r--testcases/kernel/syscalls/mq_notify/mq_notify02.c93
-rw-r--r--testcases/kernel/syscalls/mq_notify/mq_notify03.c99
-rw-r--r--testcases/kernel/syscalls/mremap/.gitignore1
-rw-r--r--testcases/kernel/syscalls/mremap/mremap06.c134
-rw-r--r--testcases/kernel/syscalls/msync/msync01.c2
-rw-r--r--testcases/kernel/syscalls/munlock/munlock01.c181
-rw-r--r--testcases/kernel/syscalls/munlock/munlock02.c212
-rw-r--r--testcases/kernel/syscalls/munmap/munmap01.c2
-rw-r--r--testcases/kernel/syscalls/munmap/munmap02.c2
-rw-r--r--testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at01.c2
-rw-r--r--testcases/kernel/syscalls/open_by_handle_at/open_by_handle_at01.c2
-rw-r--r--testcases/kernel/syscalls/personality/personality01.c93
-rw-r--r--testcases/kernel/syscalls/personality/personality02.c64
-rw-r--r--testcases/kernel/syscalls/pipe/.gitignore1
-rw-r--r--testcases/kernel/syscalls/pipe/pipe03.c51
-rw-r--r--testcases/kernel/syscalls/pipe/pipe06.c138
-rw-r--r--testcases/kernel/syscalls/pipe/pipe07.c203
-rw-r--r--testcases/kernel/syscalls/pipe/pipe08.c152
-rw-r--r--testcases/kernel/syscalls/pipe/pipe10.c178
-rw-r--r--testcases/kernel/syscalls/pipe/pipe14.c46
-rw-r--r--testcases/kernel/syscalls/prctl/prctl04.c1
-rw-r--r--testcases/kernel/syscalls/preadv2/preadv203.c2
-rw-r--r--testcases/kernel/syscalls/process_madvise/.gitignore1
-rw-r--r--testcases/kernel/syscalls/process_madvise/Makefile (renamed from testcases/kernel/syscalls/paging/Makefile)3
-rw-r--r--testcases/kernel/syscalls/process_madvise/process_madvise.h101
-rw-r--r--testcases/kernel/syscalls/process_madvise/process_madvise01.c131
-rw-r--r--testcases/kernel/syscalls/quotactl/quotactl08.c1
-rw-r--r--testcases/kernel/syscalls/readahead/readahead02.c15
-rw-r--r--testcases/kernel/syscalls/readlinkat/readlinkat01.c182
-rw-r--r--testcases/kernel/syscalls/readlinkat/readlinkat02.c127
-rw-r--r--testcases/kernel/syscalls/recvmsg/recvmsg01.c718
-rw-r--r--testcases/kernel/syscalls/sbrk/sbrk01.c121
-rw-r--r--testcases/kernel/syscalls/sbrk/sbrk02.c101
-rw-r--r--testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c3
-rw-r--r--testcases/kernel/syscalls/sendfile/sendfile04.c1
-rw-r--r--testcases/kernel/syscalls/setgroups/.gitignore2
-rw-r--r--testcases/kernel/syscalls/setgroups/setgroups01.c211
-rw-r--r--testcases/kernel/syscalls/setgroups/setgroups02.c191
-rw-r--r--testcases/kernel/syscalls/setgroups/setgroups03.c245
-rw-r--r--testcases/kernel/syscalls/setgroups/setgroups04.c163
-rw-r--r--testcases/kernel/syscalls/setpgid/setpgid02.c14
-rw-r--r--testcases/kernel/syscalls/setpgid/setpgid03.c6
-rw-r--r--testcases/kernel/syscalls/setreuid/setreuid04.c150
-rw-r--r--testcases/kernel/syscalls/setreuid/setreuid07.c196
-rw-r--r--testcases/kernel/syscalls/setsockopt/setsockopt02.c4
-rw-r--r--testcases/kernel/syscalls/setsockopt/setsockopt08.c80
-rw-r--r--testcases/kernel/syscalls/sockioctl/sockioctl01.c4
-rw-r--r--testcases/kernel/syscalls/stat/stat01.c6
-rw-r--r--testcases/kernel/syscalls/statvfs/statvfs02.c1
-rw-r--r--testcases/kernel/syscalls/statx/.gitignore3
-rw-r--r--testcases/kernel/syscalls/statx/statx01.c1
-rw-r--r--testcases/kernel/syscalls/statx/statx02.c1
-rw-r--r--testcases/kernel/syscalls/statx/statx03.c1
-rw-r--r--testcases/kernel/syscalls/statx/statx04.c3
-rw-r--r--testcases/kernel/syscalls/statx/statx05.c1
-rw-r--r--testcases/kernel/syscalls/statx/statx06.c4
-rw-r--r--testcases/kernel/syscalls/statx/statx07.c14
-rw-r--r--testcases/kernel/syscalls/statx/statx08.c1
-rw-r--r--testcases/kernel/syscalls/statx/statx09.c15
-rw-r--r--testcases/kernel/syscalls/statx/statx10.c93
-rw-r--r--testcases/kernel/syscalls/statx/statx11.c89
-rw-r--r--testcases/kernel/syscalls/statx/statx12.c95
-rw-r--r--testcases/kernel/syscalls/switch/endian_switch01.c27
-rw-r--r--testcases/kernel/syscalls/symlink/symlink01.c8
-rw-r--r--testcases/kernel/syscalls/timerfd/timerfd_create01.c99
-rw-r--r--testcases/kernel/syscalls/uname/uname04.c4
-rw-r--r--testcases/kernel/syscalls/utils/compat_uid.h2
-rw-r--r--testcases/kernel/syscalls/utils/ioprio.h46
-rw-r--r--testcases/kernel/syscalls/utime/utime02.c1
-rw-r--r--testcases/kernel/syscalls/utime/utime04.c7
-rw-r--r--testcases/kernel/syscalls/utime/utime05.c1
-rw-r--r--testcases/kernel/syscalls/utime/utime06.c9
-rw-r--r--testcases/kernel/syscalls/utimensat/utimensat01.c2
-rw-r--r--testcases/kernel/syscalls/write/write02.c17
-rw-r--r--testcases/kernel/syscalls/write/write04.c2
-rw-r--r--testcases/kernel/syscalls/write/write05.c39
-rw-r--r--testcases/lib/.gitignore8
-rw-r--r--testcases/lib/Makefile3
-rw-r--r--testcases/lib/tst_fsfreeze.c38
-rw-r--r--testcases/lib/tst_get_free_pids.c2
-rw-r--r--testcases/lib/tst_kvcmp.c2
-rw-r--r--testcases/lib/tst_lockdown_enabled.c12
-rw-r--r--testcases/lib/tst_net.sh228
-rw-r--r--testcases/lib/tst_ns_common.h (renamed from testcases/kernel/containers/share/ns_common.h)6
-rw-r--r--testcases/lib/tst_ns_create.c92
-rw-r--r--testcases/lib/tst_ns_exec.c115
-rw-r--r--testcases/lib/tst_ns_ifmove.c92
-rw-r--r--testcases/lib/tst_secureboot_enabled.c12
-rw-r--r--testcases/lib/tst_test.sh14
-rwxr-xr-xtestcases/network/iptables/iptables_lib.sh8
-rw-r--r--testcases/network/lib6/asapi_01.c2
-rw-r--r--testcases/network/lib6/asapi_02.c336
-rw-r--r--testcases/network/lib6/asapi_03.c2
-rw-r--r--testcases/network/netstress/netstress.c1
-rw-r--r--testcases/network/nfs/nfs_stress/Makefile9
-rwxr-xr-xtestcases/network/nfs/nfs_stress/nfs03.sh2
-rwxr-xr-xtestcases/network/nfs/nfs_stress/nfs05.sh6
-rwxr-xr-xtestcases/network/nfs/nfs_stress/nfs06.sh5
-rwxr-xr-xtestcases/network/nfs/nfs_stress/nfs08.sh23
-rw-r--r--testcases/network/nfs/nfs_stress/nfs_lib.sh80
-rw-r--r--testcases/network/nfs/nfslock01/nfs_flock.c72
-rw-r--r--testcases/network/nfs/nfslock01/nfs_flock.h6
-rw-r--r--testcases/network/nfs/nfslock01/nfs_flock_dgen.c39
-rw-r--r--testcases/network/nfs/nfslock01/nfs_flock_func.c6
-rwxr-xr-xtestcases/network/nfs/nfslock01/nfslock01.sh45
-rw-r--r--testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast.c3
-rw-r--r--testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_complex.c3
-rw-r--r--testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_dataint.c15
-rw-r--r--testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_performance.c2
-rw-r--r--testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_scalability.c2
-rw-r--r--testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_stress.c2
-rw-r--r--testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_regunreg_registerrpc/rpc_registerrpc.c5
-rw-r--r--testcases/network/sctp/sctp_big_chunk.c35
-rw-r--r--testcases/network/sockets/vsock01.c3
-rw-r--r--testcases/network/stress/udp/multi-diffip/udp4-multi-diffip012
-rwxr-xr-xtestcases/network/tcp_cmds/ipneigh/ipneigh01.sh2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/aio_read/8-1.c2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/aio_read/assertions.xml8
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/aio_write/6-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/aio_write/assertions.xml8
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/fork/assertions.xml2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/lio_listio/13-1.c2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/lio_listio/assertions.xml2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/mmap/6-5.c2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getinheritsched/assertions.xml2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getscope/assertions.xml2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_destroy/3-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_init/3-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_detach/3-1.c4
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_destroy/3-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_init/4-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_lock/2-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_trylock/3-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_unlock/3-1.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/pthread_sigmask/5-1.c2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/raise/2-1.c2
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-1.c4
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-2.c3
-rw-r--r--testcases/open_posix_testsuite/conformance/interfaces/sigqueue/assertions.xml2
-rw-r--r--testcases/realtime/func/matrix_mult/matrix_mult.c2
-rw-r--r--testcases/realtime/tools/ftqviz.py2
-rwxr-xr-xtestscripts/network.sh7
-rwxr-xr-xtools/create-tarballs-metadata.sh56
-rwxr-xr-xtools/lib.sh31
-rw-r--r--tools/ltx/Makefile31
m---------tools/runltp-ng0
-rwxr-xr-xtools/tag-release.sh45
-rw-r--r--utils/benchmark/ebizzy-0.3/ebizzy.c20
-rwxr-xr-xver_linux8
625 files changed, 13219 insertions, 17907 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d8e5dca86..d7e9f2dd0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-# Copyright (c) 2021 Petr Vorel <pvorel@suse.cz>
+# Copyright (c) 2021-2023 Petr Vorel <pvorel@suse.cz>
name: "CI: docker based builds"
on: [push, pull_request]
@@ -79,7 +79,6 @@ jobs:
- container: "debian:oldstable"
env:
CC: clang
- METADATA: asciidoc-pdf
- container: "opensuse/leap"
env:
diff --git a/.github/workflows/wiki-mirror.yml b/.github/workflows/wiki-mirror.yml
index 883892bf5..2ac0caf74 100644
--- a/.github/workflows/wiki-mirror.yml
+++ b/.github/workflows/wiki-mirror.yml
@@ -38,20 +38,10 @@ jobs:
commit=$(git log --pretty=format:"%h (\"%s\")" -1 .)
cd $GITHUB_WORKSPACE/ltp.wiki
-
- # Don't forget to update this list, keep it sorted
- cp -v $dir/c-test-api.txt C-Test-API.asciidoc
- cp -v $dir/c-test-tutorial-simple.txt C-Test-Case-Tutorial.asciidoc
- cp -v $dir/library-api-writing-guidelines.txt LTP-Library-API-Writing-Guidelines.asciidoc
- cp -v $dir/maintainer-patch-review-checklist.txt Maintainer-Patch-Review-Checklist.asciidoc
- cp -v $dir/network-c-api.txt C-Test-Network-API.asciidoc
- cp -v $dir/shell-test-api.txt Shell-Test-API.asciidoc
- cp -v $dir/supported-kernel-libc-versions.txt Supported-kernel,-libc,-toolchain-versions.asciidoc
- cp -v $dir/test-writing-guidelines.txt Test-Writing-Guidelines.asciidoc
- cp -v $dir/user-guide.txt User-Guidelines.asciidoc
- cp -v $dir/kvm-test-api.txt KVM-Test-API.asciidoc
-
+ # don't forget to add new extensions
+ cp -v $dir/*.asciidoc $dir/*.rest .
git add .
+
# only commit if there are changes
git diff-index --quiet HEAD -- || git commit -m "Update to $commit" .
git push
diff --git a/.gitignore b/.gitignore
index 335c33883..9aa8b0588 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,16 +34,12 @@ autom4te.cache
/m4/Makefile
/m4/Makefile.in
-/execltp
-/ltp-devel.spec
-/README.ltp-devel
/tags
/Version
/include/mk/config.mk
/include/mk/config-openposix.mk
/include/mk/features.mk
/m4/ltp-version.m4
-/lib/ltp.pc
/pan/ltp-bump
/pan/ltp-pan
@@ -65,22 +61,5 @@ patches/
logfile.*
/utils/benchmark/ebizzy-0.3/ebizzy
-/lib/tests/tst_tmpdir_test
-/lib/tests/tst_checkpoint
-/lib/tests/tst_checkpoint_wait_timeout
-/lib/tests/tst_checkpoint_wake_timeout
-/lib/tests/tst_process_state
-/lib/tests/tst_cleanup_once
-/lib/tests/tst_safe_macros
-/lib/tests/tst_strsig
-/lib/tests/tst_strerrno
-/lib/tests/tst_fs_fill_subdirs
-/lib/tests/tst_fs_fill_hardlinks
-/lib/tests/tst_device
-/lib/tests/tst_record_childstatus
-/lib/tests/trerrno
-/lib/tests/tst_dataroot01
-/lib/tests/tst_dataroot02
-/lib/tests/tst_dataroot03
*.dump
diff --git a/Android.bp b/Android.bp
index df0552ab7..055dd9b0f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -75,6 +75,15 @@ genrule {
out: ["lapi/syscalls.h"],
}
+genrule {
+ name: "ltp_version_h",
+ srcs: [
+ "VERSION",
+ ],
+ cmd: "echo \"#define LTP_VERSION \\\"$$(cat $(in))\\\"\" > $(out)",
+ out: ["ltp-version.h"],
+}
+
cc_defaults {
name: "ltp_defaults",
@@ -129,7 +138,10 @@ cc_defaults {
},
},
- generated_headers: ["ltp_syscalls_h"],
+ generated_headers: [
+ "ltp_syscalls_h",
+ "ltp_version_h",
+ ],
static_libs: ["libcap"],
diff --git a/Makefile b/Makefile
index cb80622d6..53f94d9f7 100644
--- a/Makefile
+++ b/Makefile
@@ -146,7 +146,6 @@ clean:: $(CLEAN_TARGETS)
$(foreach tgt,$(MAKE_TARGETS) include-all lib-all $(filter-out clean_install_dir,$(CLEAN_TARGETS)) $(INSTALL_TARGETS) include-install lib-install,$(eval $(call target_to_dir_dep_mapping,$(tgt))))
-BINDIR_INSTALL_SCRIPTS := execltp
SRCDIR_INSTALL_SCRIPTS := IDcheck.sh runltp ver_linux
SRCDIR_INSTALL_READONLY := Version
SRCDIR_INSTALL_TARGETS := $(SRCDIR_INSTALL_SCRIPTS) $(SRCDIR_INSTALL_READONLY)
diff --git a/Makefile.release b/Makefile.release
deleted file mode 100644
index c81925de5..000000000
--- a/Makefile.release
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Release Makefile for LTP.
-#
-# Copyright (C) 2010, Copyrights-are-for-losers, 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Invoke like:
-#
-# make -f Makefile.release release TARBALL_VERSION=FOO
-#
-# Cheers.
-#
-
-top_srcdir ?= $(CURDIR)
-
-include $(top_srcdir)/include/mk/env_pre.mk
-include $(top_srcdir)/include/mk/automake.mk
-
-TARBALL_PREFIX ?= ltp
-
-ifneq ($(wildcard $(top_srcdir)/Version),)
-TARBALL_VERSION ?= $(shell $(top_srcdir)/Version)
-endif
-
-TARBALL_VERSION ?= $(error you must either make Version via make $$PWD/Version or specify an LTP version via TARBALL_VERSION)
-
-TARBALL := $(TARBALL_PREFIX)-$(TARBALL_VERSION).tgz
-
-clean:
- $(MAKE) -f Makefile $@
-
-release: | autotools distclean
- tar -cvz --exclude "$(TARBALL)" -f $(TARBALL) .
diff --git a/README.md b/README.md
index d7cb4d346..68f6ec897 100644
--- a/README.md
+++ b/README.md
@@ -101,8 +101,7 @@ $ make install
```
This will install LTP to `/opt/ltp`.
-* If you have a problem see `doc/mini-howto-building-ltp-from-git.txt`.
-* If you still have a problem see `INSTALL` and `./configure --help`.
+* If you have a problem see `INSTALL` and `./configure --help`.
* Failing that, ask for help on the mailing list or Github.
Some tests will be disabled if the configure script can not find their build
diff --git a/VERSION b/VERSION
index af4c41fec..e851466ff 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-20230127
+20230929
diff --git a/android/Android.ltp.mk b/android/Android.ltp.mk
index b038104d2..4d29e2ab7 100644
--- a/android/Android.ltp.mk
+++ b/android/Android.ltp.mk
@@ -81,18 +81,10 @@ module_prebuilt := testcases/data/file01/in.c
module_src_files := testcases/commands/file/datafiles/in.c
include $(ltp_build_prebuilt)
-module_prebuilt := testcases/data/file01/in.csh
-module_src_files := testcases/commands/file/datafiles/in.csh
-include $(ltp_build_prebuilt)
-
module_prebuilt := testcases/data/file01/in.jpg
module_src_files := testcases/commands/file/datafiles/in.jpg
include $(ltp_build_prebuilt)
-module_prebuilt := testcases/data/file01/in.ksh
-module_src_files := testcases/commands/file/datafiles/in.ksh
-include $(ltp_build_prebuilt)
-
module_prebuilt := testcases/data/file01/in.m4
module_src_files := testcases/commands/file/datafiles/in.m4
include $(ltp_build_prebuilt)
diff --git a/android/README.md b/android/README.md
index 60462723d..3cda88e39 100644
--- a/android/README.md
+++ b/android/README.md
@@ -258,6 +258,12 @@ periodically running:
`git clean -dfx && make autotools && ./configure && make -j`
+Commit the LTP version string
+```
+git describe <release commit> > VERSION
+git add VERSION
+```
+
### Update the Android build targets
Building LTP with the Android build system requires the additional Android
@@ -278,4 +284,4 @@ differences in the test suite.
LTP_NEW=$ANDROID_BUILD_TOP/external/ltp
LTP_OLD=/tmp/ltp-base
git archive aosp/master | tar -x -C $LTP_OLD
-android/tools/compare_ltp_projects.py --ltp-new $LTP_NEW --ltp-old $LTP_OLD
+android/tools/compare_ltp_projects.py --ltp-new $LTP_NEW --ltp-old $LTP_OLD \ No newline at end of file
diff --git a/android/include/config.h b/android/include/config.h
index 951da923d..514f10a18 100644
--- a/android/include/config.h
+++ b/android/include/config.h
@@ -111,6 +111,9 @@
/* Define to 1 if you have `io_set_eventfd' function. */
/* #undef HAVE_IO_SET_EVENTFD */
+/* Define to 1 if you have the <linux/ioprio.h> header file. */
+#define HAVE_LINUX_IOPRIO_H 1
+
/* Define to 1 if you have the `kcmp' function. */
/* #undef HAVE_KCMP */
diff --git a/android/ltp_package_list.mk b/android/ltp_package_list.mk
index 1e2d2aba6..49c8510d6 100644
--- a/android/ltp_package_list.mk
+++ b/android/ltp_package_list.mk
@@ -90,6 +90,7 @@ ltp_packages := \
ltp_cfs_bandwidth01 \
ltp_cgroup_core01 \
ltp_cgroup_core02 \
+ ltp_cgroup_core03 \
ltp_cgroup_fj_proc \
ltp_cgroup_regression_fork_processes \
ltp_cgroup_regression_getdelays \
@@ -140,6 +141,7 @@ ltp_packages := \
ltp_clone09 \
ltp_clone301 \
ltp_clone302 \
+ ltp_clone303 \
ltp_close01 \
ltp_close02 \
ltp_close_range01 \
@@ -256,8 +258,16 @@ ltp_packages := \
ltp_epoll_wait02 \
ltp_epoll_wait03 \
ltp_epoll_wait04 \
+ ltp_epoll_wait05 \
+ ltp_epoll_wait06 \
+ ltp_epoll_wait07 \
ltp_event_generator \
ltp_eventfd01 \
+ ltp_eventfd02 \
+ ltp_eventfd03 \
+ ltp_eventfd04 \
+ ltp_eventfd05 \
+ ltp_eventfd06 \
ltp_eventfd2_01 \
ltp_eventfd2_02 \
ltp_eventfd2_03 \
@@ -294,6 +304,9 @@ ltp_packages := \
ltp_f2 \
ltp_f3 \
ltp_faccessat01 \
+ ltp_faccessat02 \
+ ltp_faccessat201 \
+ ltp_faccessat202 \
ltp_fallocate01 \
ltp_fallocate02 \
ltp_fallocate03 \
@@ -357,8 +370,6 @@ ltp_packages := \
ltp_fcntl04_64 \
ltp_fcntl05 \
ltp_fcntl05_64 \
- ltp_fcntl06 \
- ltp_fcntl06_64 \
ltp_fcntl07 \
ltp_fcntl07_64 \
ltp_fcntl08 \
@@ -470,6 +481,7 @@ ltp_packages := \
ltp_fs_perms \
ltp_fsconfig01 \
ltp_fsconfig02 \
+ ltp_fsconfig03 \
ltp_fsetxattr01 \
ltp_fsetxattr02 \
ltp_fsmount01 \
@@ -675,6 +687,7 @@ ltp_packages := \
ltp_hugemmap29 \
ltp_hugemmap30 \
ltp_hugemmap31 \
+ ltp_hugemmap32 \
ltp_icmp_rate_limit01 \
ltp_ima_boot_aggregate \
ltp_ima_mmap \
@@ -829,6 +842,7 @@ ltp_packages := \
ltp_madvise08 \
ltp_madvise09 \
ltp_madvise10 \
+ ltp_madvise11 \
ltp_mallinfo01 \
ltp_mallinfo02 \
ltp_mallinfo2_01 \
@@ -907,7 +921,6 @@ ltp_packages := \
ltp_mmap04 \
ltp_mmap05 \
ltp_mmap06 \
- ltp_mmap07 \
ltp_mmap08 \
ltp_mmap09 \
ltp_mmap1 \
@@ -922,6 +935,7 @@ ltp_packages := \
ltp_mmap18 \
ltp_mmap19 \
ltp_mmap2 \
+ ltp_mmap20 \
ltp_mmap3 \
ltp_mmapstress01 \
ltp_mmapstress02 \
@@ -945,6 +959,7 @@ ltp_packages := \
ltp_mount04 \
ltp_mount05 \
ltp_mount06 \
+ ltp_mount07 \
ltp_mount_setattr01 \
ltp_move_mount01 \
ltp_move_mount02 \
@@ -963,10 +978,12 @@ ltp_packages := \
ltp_mprotect02 \
ltp_mprotect03 \
ltp_mprotect04 \
+ ltp_mprotect05 \
ltp_mremap01 \
ltp_mremap02 \
ltp_mremap03 \
ltp_mremap05 \
+ ltp_mremap06 \
ltp_msgget05 \
ltp_msync01 \
ltp_msync02 \
@@ -985,7 +1002,6 @@ ltp_packages := \
ltp_nanosleep02 \
ltp_nanosleep04 \
ltp_netstress \
- ltp_newns \
ltp_newuname01 \
ltp_nextafter01 \
ltp_nfs01_open_files \
@@ -1079,6 +1095,7 @@ ltp_packages := \
ltp_pipe11 \
ltp_pipe12 \
ltp_pipe13 \
+ ltp_pipe14 \
ltp_pipe2_01 \
ltp_pipe2_02 \
ltp_pipe2_02_child \
@@ -1126,6 +1143,7 @@ ltp_packages := \
ltp_preadv203_64 \
ltp_print_caps \
ltp_proc01 \
+ ltp_process_madvise01 \
ltp_process_vm01 \
ltp_process_vm_readv02 \
ltp_process_vm_readv03 \
@@ -1359,8 +1377,6 @@ ltp_packages := \
ltp_setgroups02_16 \
ltp_setgroups03 \
ltp_setgroups03_16 \
- ltp_setgroups04 \
- ltp_setgroups04_16 \
ltp_sethostname01 \
ltp_sethostname02 \
ltp_sethostname03 \
@@ -1484,6 +1500,7 @@ ltp_packages := \
ltp_ssetmask01 \
ltp_stack_clash \
ltp_stack_space \
+ ltp_starvation \
ltp_stat01 \
ltp_stat01_64 \
ltp_stat02 \
@@ -1505,6 +1522,9 @@ ltp_packages := \
ltp_statx06 \
ltp_statx08 \
ltp_statx09 \
+ ltp_statx10 \
+ ltp_statx11 \
+ ltp_statx12 \
ltp_stream01 \
ltp_stream02 \
ltp_stream03 \
@@ -1547,6 +1567,7 @@ ltp_packages := \
ltp_syslog11 \
ltp_syslog12 \
ltp_tbio \
+ ltp_tcindex01 \
ltp_tee01 \
ltp_tee02 \
ltp_test01 \
@@ -1957,6 +1978,7 @@ ltp_packages := \
ltp_testcases_bin_nfs05.sh \
ltp_testcases_bin_nfs06.sh \
ltp_testcases_bin_nfs07.sh \
+ ltp_testcases_bin_nfs08.sh \
ltp_testcases_bin_nfs_lib.sh \
ltp_testcases_bin_nfslock01.sh \
ltp_testcases_bin_nfsstat01.sh \
@@ -2352,7 +2374,6 @@ ltp_packages := \
ltp_testcases_bin_test_controllers.sh \
ltp_testcases_bin_test_ioctl \
ltp_testcases_bin_test_robind.sh \
- ltp_testcases_bin_testall.sh \
ltp_testcases_bin_tracepath01.sh \
ltp_testcases_bin_traceroute01.sh \
ltp_testcases_bin_tst_ansi_color.sh \
@@ -2448,9 +2469,7 @@ ltp_packages := \
ltp_testcases_data_file01_in.ar \
ltp_testcases_data_file01_in.bash \
ltp_testcases_data_file01_in.c \
- ltp_testcases_data_file01_in.csh \
ltp_testcases_data_file01_in.jpg \
- ltp_testcases_data_file01_in.ksh \
ltp_testcases_data_file01_in.m4 \
ltp_testcases_data_file01_in.mp3 \
ltp_testcases_data_file01_in.pl \
@@ -2519,14 +2538,6 @@ ltp_packages := \
ltp_times03 \
ltp_tkill01 \
ltp_tkill02 \
- ltp_tomoyo_accept_test \
- ltp_tomoyo_file_test \
- ltp_tomoyo_filesystem_test \
- ltp_tomoyo_new_file_test \
- ltp_tomoyo_new_test \
- ltp_tomoyo_policy_io_test \
- ltp_tomoyo_policy_memory_test \
- ltp_tomoyo_rewrite_test \
ltp_tpci \
ltp_trace_sched \
ltp_trerrno \
@@ -2557,6 +2568,7 @@ ltp_packages := \
ltp_tst_fs_fill_hardlinks \
ltp_tst_fs_fill_subdirs \
ltp_tst_fs_has_free \
+ ltp_tst_fsfreeze \
ltp_tst_fuzzy_sync01 \
ltp_tst_fuzzy_sync02 \
ltp_tst_fuzzy_sync03 \
@@ -2566,6 +2578,7 @@ ltp_packages := \
ltp_tst_getconf \
ltp_tst_hexdump \
ltp_tst_kvcmp \
+ ltp_tst_lockdown_enabled \
ltp_tst_ncpus \
ltp_tst_ncpus_conf \
ltp_tst_ncpus_max \
@@ -2580,6 +2593,9 @@ ltp_packages := \
ltp_tst_net_iface_prefix \
ltp_tst_net_ip_prefix \
ltp_tst_net_vars \
+ ltp_tst_ns_create \
+ ltp_tst_ns_exec \
+ ltp_tst_ns_ifmove \
ltp_tst_print_result \
ltp_tst_process_state \
ltp_tst_random \
@@ -2590,6 +2606,7 @@ ltp_packages := \
ltp_tst_rod \
ltp_tst_safe_fileops \
ltp_tst_safe_macros \
+ ltp_tst_secureboot_enabled \
ltp_tst_sleep \
ltp_tst_strerrno \
ltp_tst_strsig \
@@ -2628,6 +2645,10 @@ ltp_packages := \
ltp_utime06 \
ltp_utimensat01 \
ltp_utimes01 \
+ ltp_utsname01 \
+ ltp_utsname02 \
+ ltp_utsname03 \
+ ltp_utsname04 \
ltp_variant \
ltp_verify_caps_exec \
ltp_vfork \
diff --git a/android/tools/android_build_generator.py b/android/tools/android_build_generator.py
index 9d674059b..2ef583242 100644
--- a/android/tools/android_build_generator.py
+++ b/android/tools/android_build_generator.py
@@ -363,6 +363,8 @@ class BuildGenerator(object):
# some targets may have a mix of .c and .o files in srcs
# find the .c files to build those .o from cc_compile targets
if i.endswith('.o'):
+ if i not in cc_compile:
+ raise Exception("Not found: %s when trying to compile target %s" % (i, target))
local_src_files.extend(cc_compile[i])
else:
local_src_files.append(i)
diff --git a/android/tools/compare_ltp_projects.py b/android/tools/compare_ltp_projects.py
index 33e06ec0e..0863bdf8a 100755
--- a/android/tools/compare_ltp_projects.py
+++ b/android/tools/compare_ltp_projects.py
@@ -134,21 +134,20 @@ def show_diff(ltp_tests_1, ltp_tests_2):
ltp_tests_1: dictionary of tests keyed by test suite names
ltp_tests_2: dictionary of tests keyed by test suite names
'''
- DEFAULT_WIDTH = 8
- test_suites1 = set(sorted(ltp_tests_1.keys()))
- test_suites2 = set(sorted(ltp_tests_2.keys()))
+ test_suites1 = set(ltp_tests_1.keys())
+ test_suites2 = set(ltp_tests_2.keys())
# Generate lists of deleted, added and common test suites between
# LTP1 & LTP2
deleted_test_suites = sorted(test_suites1.difference(test_suites2))
added_test_suites = sorted(test_suites2.difference(test_suites1))
- common_test_suites = sorted(test_suites1.intersection(test_suites2))
+ common_test_suites = test_suites1.intersection(test_suites2)
deleted_tests = []
added_tests = []
for suite in common_test_suites:
- tests1 = set(sorted(ltp_tests_1[suite]))
- tests2 = set(sorted(ltp_tests_2[suite]))
+ tests1 = set(ltp_tests_1[suite])
+ tests2 = set(ltp_tests_2[suite])
exclusive_test1 = tests1.difference(tests2)
exclusive_test2 = tests2.difference(tests1)
@@ -156,7 +155,13 @@ def show_diff(ltp_tests_1, ltp_tests_2):
deleted_tests.append(suite + '.' + e)
for e in exclusive_test2:
added_tests.append(suite + '.' + e)
+ deleted_tests = sorted(deleted_tests)
+ added_tests = sorted(added_tests)
+ print_columns(added_test_suites, deleted_test_suites, added_tests, deleted_tests)
+
+def print_columns(added_test_suites, deleted_test_suites, added_tests, deleted_tests):
+ DEFAULT_WIDTH = 8
# find the maximum width of a test suite name or test name
# we have to print to decide the alignment.
if not deleted_test_suites:
@@ -172,26 +177,26 @@ def show_diff(ltp_tests_1, ltp_tests_2):
# total rows we have to print
total_rows = max(len(deleted_test_suites), len(added_test_suites))
- deleted_text = 'Deleted ({})'.format(len(deleted_test_suites))
added_text = 'Added ({})'.format(len(added_test_suites))
+ deleted_text = 'Deleted ({})'.format(len(deleted_test_suites))
if total_rows > 0:
print('{:*^{len}}'.format(' Tests Suites ', len=width*2+2))
- print('{:>{len}} {:>{len}}'.format(deleted_text, added_text, len=width))
+ print('{:<{len}} {:<{len}}'.format(added_text, deleted_text, len=width))
for i in range(total_rows):
- print('{:>{len}} {:>{len}}'.format('' if i >= len(deleted_test_suites) else str(deleted_test_suites[i]),
- '' if i >= len(added_test_suites) else str(added_test_suites[i]), len=width))
+ print('{:<{len}} {:<{len}}'.format('' if i >= len(added_test_suites) else str(added_test_suites[i]),
+ '' if i >= len(deleted_test_suites) else str(deleted_test_suites[i]), len=width))
print('')
# total rows we have to print
total_rows = max(len(deleted_tests), len(added_tests))
- deleted_text = 'Deleted ({})'.format(len(deleted_tests))
added_text = 'Added ({})'.format(len(added_tests))
+ deleted_text = 'Deleted ({})'.format(len(deleted_tests))
if total_rows:
print('{:*^{len}}'.format(' Tests ', len=width*2+2))
- print('{:>{len}} {:>{len}}'.format(deleted_text, added_text, len=width))
+ print('{:^{len}} {:^{len}}'.format(added_text, deleted_text, len=width))
for i in range(total_rows):
- print('{:>{len}} {:>{len}}'.format('' if i >= len(deleted_tests) else str(deleted_tests[i]),
- '' if i >= len(added_tests) else str(added_tests[i]), len=width))
+ print('{:<{len}} {:<{len}}'.format('' if i >= len(added_tests) else str(added_tests[i]),
+ '' if i >= len(deleted_tests) else str(deleted_tests[i]), len=width))
def main():
arg_parser = argparse.ArgumentParser(
description='Diff 2 LTP projects for supported test cases')
diff --git a/android/tools/disabled_libs.txt b/android/tools/disabled_libs.txt
index f2ede3289..0f648ab32 100644
--- a/android/tools/disabled_libs.txt
+++ b/android/tools/disabled_libs.txt
@@ -1,2 +1,4 @@
# List of tests which cannot (currently) be built for Android/bionic.
# Every test case that requires this lib will also need be disabled
+
+bootstrap_x86_64
diff --git a/android/tools/disabled_tests.txt b/android/tools/disabled_tests.txt
index e545c21fe..dfa8902ee 100644
--- a/android/tools/disabled_tests.txt
+++ b/android/tools/disabled_tests.txt
@@ -355,6 +355,7 @@ pipeio
mq_timedsend01
mq_notify01
mq_notify02
+mq_notify03
mq_open01
mq_timedreceive01
mq_unlink01
@@ -617,6 +618,12 @@ set_mempolicy05
# b/246845416
kvm_pagefault01
kvm_pagefault01-payload.elf
+kvm_svm01
+kvm_svm01-payload.elf
+kvm_svm02
+kvm_svm02-payload.elf
+kvm_svm03
+kvm_svm03-payload.elf
# Redefines cacheflush
# b/277960476
diff --git a/android/tools/make_install_parser.py b/android/tools/make_install_parser.py
index bc94d7e76..75d9fa3f8 100644..100755
--- a/android/tools/make_install_parser.py
+++ b/android/tools/make_install_parser.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
#
# Copyright 2016 - The Android Open Source Project
#
diff --git a/android/tools/make_parser.py b/android/tools/make_parser.py
index d845569fe..59796c4aa 100644..100755
--- a/android/tools/make_parser.py
+++ b/android/tools/make_parser.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
#
# Copyright 2016 - The Android Open Source Project
#
@@ -23,6 +24,7 @@ import fileinput
import pprint
AR = 'ar'
+AS = 'as'
CC = 'gcc'
class MakeParser(object):
@@ -31,6 +33,7 @@ class MakeParser(object):
Attributes:
ltp_root: string, LTP root directory
ar_parser: archive (ar) command argument parser
+ as_parser: assembly (as) command argument parser
cc_parser: gcc command argument parser
result: list of string, result string buffer
dir_stack: list of string, directory stack for parsing make commands
@@ -43,6 +46,11 @@ class MakeParser(object):
ar_parser.add_argument('-c', dest='c', action='store')
self.ar_parser = ar_parser
+ as_parser = argparse.ArgumentParser()
+ as_parser.add_argument('-c', dest='compile', action='store_true')
+ as_parser.add_argument('-o', dest='target', action='store')
+ self.as_parser = as_parser
+
cc_parser = argparse.ArgumentParser()
cc_parser.add_argument('-D', dest='defines', action='append')
cc_parser.add_argument('-I', dest='includes', action='append')
@@ -78,10 +86,10 @@ class MakeParser(object):
return [self.GetRelativePath(i) for i in paths if i[-1] in extensions]
def ParseAr(self, line):
- '''Parse a archive command line.
+ '''Parse an archive command line.
Args:
- line: string, a line of ar command to parse
+ line: string, a line of as command to parse
'''
args, unparsed = self.ar_parser.parse_known_args(line.split()[1:])
@@ -105,6 +113,24 @@ class MakeParser(object):
self.result.append("ar['%s'] = %s" % (target, sources))
+ def ParseAs(self, line):
+ '''Parse an assembly command line.
+
+ Args:
+ line: string, a line of as command to parse
+ '''
+ args, unparsed = self.as_parser.parse_known_args(line.split()[1:])
+
+ sources = self.GetRelativePathForExtensions(unparsed, ['S'])
+
+ assert len(sources) > 0
+ target = self.GetRelativePath(args.target)
+
+ if args.compile:
+ self.result.append("cc_compile['%s'] = %s" % (target, sources))
+ else:
+ raise Exception("Unparsed assembly line: %s" % line)
+
def ParseCc(self, line):
'''Parse a gcc command line.
@@ -179,6 +205,8 @@ class MakeParser(object):
self.dir_stack.pop()
elif line.startswith(AR):
self.ParseAr(line)
+ elif line.startswith(AS):
+ self.ParseAs(line)
elif line.startswith(CC):
self.ParseCc(line)
diff --git a/ci/debian.minimal.sh b/ci/debian.minimal.sh
index c314d93fe..b51154b05 100755
--- a/ci/debian.minimal.sh
+++ b/ci/debian.minimal.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (c) 2018-2020 Petr Vorel <pvorel@suse.cz>
+# Copyright (c) 2018-2023 Petr Vorel <pvorel@suse.cz>
set -ex
apt="apt remove -y"
@@ -11,7 +11,6 @@ $apt \
libaio-dev \
libaio1 \
libcap-dev \
- libcap2 \
libkeyutils-dev \
libnuma-dev \
libnuma1 \
diff --git a/configure.ac b/configure.ac
index 3a418d4b3..4ba57fca3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,7 +10,6 @@ AC_CONFIG_FILES([ \
include/mk/features.mk \
lib/ltp.pc \
m4/Makefile \
- execltp \
])
AC_ARG_VAR(HOSTCC, [The C compiler on the host])
@@ -57,6 +56,7 @@ AC_CHECK_HEADERS_ONCE([ \
linux/if_ether.h \
linux/if_packet.h \
linux/io_uring.h \
+ linux/ioprio.h \
linux/keyctl.h \
linux/mempolicy.h \
linux/module.h \
@@ -93,6 +93,7 @@ AC_CHECK_FUNCS_ONCE([ \
epoll_pwait \
epoll_pwait2 \
execveat \
+ faccessat2 \
fallocate \
fchownat \
fsconfig \
@@ -160,7 +161,7 @@ AC_CHECK_FUNCS(mkdtemp,[],AC_MSG_ERROR(mkdtemp() not found!))
AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>])
AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>])
AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>])
-AC_CHECK_MEMBERS([struct statx.stx_mnt_id],,,[
+AC_CHECK_MEMBERS([struct statx.stx_mnt_id, struct statx.stx_dio_mem_align],,,[
#define _GNU_SOURCE
#include <sys/stat.h>
])
@@ -236,10 +237,10 @@ AC_CHECK_TYPES([struct __kernel_old_timeval, struct __kernel_old_timespec, struc
AC_CHECK_TYPES([struct futex_waitv],,,[#include <linux/futex.h>])
AC_CHECK_TYPES([struct mount_attr],,,[
-#ifdef HAVE_LINUX_MOUNT_H
-# include <linux/mount.h>
-#else
+#ifdef HAVE_MOUNT_SETATTR
# include <sys/mount.h>
+#elif HAVE_LINUX_MOUNT_H
+# include <linux/mount.h>
#endif
])
diff --git a/doc/build-system-guide.txt b/doc/Build-System.rest
index b8d267b4b..e078fa7f7 100644
--- a/doc/build-system-guide.txt
+++ b/doc/Build-System.rest
@@ -106,7 +106,7 @@ The 'REQ_VERSION_MAJOR' and 'REQ_VERSION_PATCH' describe minimal kernel
version for which the build system tries to build the module.
The buildsystem is also forward compatible with changes in Linux kernel
-internal API so that if modul fails to build the failure is ignored both on
+internal API so that if module fails to build the failure is ignored both on
build and installation. If the userspace counterpart of the test fails to load
the module because the file does not exists, the test is skipped.
diff --git a/doc/c-test-api.txt b/doc/C-Test-API.asciidoc
index 11f87def2..dab811564 100644
--- a/doc/c-test-api.txt
+++ b/doc/C-Test-API.asciidoc
@@ -20,7 +20,7 @@ Let's start with an example, following code is a simple test for a 'getenv()'.
* [Description]
* Tests basic functionality of getenv().
*
- * - create an env variable and verify that getenv() can get get it
+ * - create an env variable and verify that getenv() can get it
* - call getenv() with nonexisting variable name, check that it returns NULL
*/
@@ -36,7 +36,7 @@ static void setup(void)
tst_brk(TBROK | TERRNO, "setenv() failed");
}
-static void test(void)
+static void run(void)
{
char *ret;
@@ -64,7 +64,7 @@ next:
}
static struct tst_test test = {
- .test_all = test,
+ .test_all = run,
.setup = setup,
};
-------------------------------------------------------------------------------
@@ -102,7 +102,7 @@ that should cover the duration of test setup and cleanup plus some safety.
Any test that runs for more than a second or two has to make sure to:
- set the runtime either by setting the '.max_runtime' in tst_test or by
- calling 'tst_set_runtime()' in the test setup
+ calling 'tst_set_max_runtime()' in the test setup
- monitor remaning runtime by regular calls to 'tst_remaining_runtime()' and
exit when runtime has been used up
@@ -257,7 +257,7 @@ value and errno and reports the test result.
[source,c]
-------------------------------------------------------------------------------
-static void test(void)
+static void run(void)
{
...
TST_EXP_PASS(stat(fname, &statbuf), "stat(%s, ...)", fname);
@@ -278,7 +278,7 @@ begin with a format string and then appropriate values to be formatted.
[source,c]
-------------------------------------------------------------------------------
-static void test(void)
+static void run(void)
{
...
TST_EXP_FD(open(fname, O_RDONLY), "open(%s, O_RDONLY)", fname);
@@ -294,7 +294,7 @@ positive integer is returned.
[source,c]
-------------------------------------------------------------------------------
-static void test(void)
+static void run(void)
{
...
TST_EXP_FAIL(stat(fname, &statbuf), ENOENT, "stat(%s, ...)", fname);
@@ -308,7 +308,7 @@ passed as the second argument.
[source,c]
-------------------------------------------------------------------------------
-static void test(void)
+static void run(void)
{
...
TST_EXP_FAIL2(msgget(key, flags), EINVAL, "msgget(%i, %i)", key, flags);
@@ -353,8 +353,8 @@ if (!TST_PASS)
return;
-------------------------------------------------------------------------------
-If the return value of 'wait' is positive. This macro will print a pass result
-and set +TST_PASS+ appropriately. If the return value is zero or negative, then
+If the return value of 'wait' is positive or zero, this macro will print a pass
+result and set +TST_PASS+ appropriately. If the return value is negative, then
it will print fail. There are many similar macros to those shown here, please
see 'tst_test_macros.h'.
@@ -402,7 +402,7 @@ WARNING: This function is not thread safe.
void tst_set_max_runtime(int max_runtime);
-------------------------------------------------------------------------------
-Allows for setting max_runtime per test iteration dynamically in the test setup(),
+Allows for setting max_runtime per test iteration dynamically in the test 'setup()',
the timeout is specified in seconds. There are a few testcases whose runtime
can vary arbitrarily, these can disable timeouts by setting it to
TST_UNLIMITED_RUNTIME.
@@ -447,19 +447,19 @@ Instead of writing:
[source,c]
-------------------------------------------------------------------------------
- fd = open("/dev/null", O_RDONLY);
- if (fd < 0)
- tst_brk(TBROK | TERRNO, "opening /dev/null failed");
+fd = open("/dev/null", O_RDONLY);
+if (fd < 0)
+ tst_brk(TBROK | TERRNO, "opening /dev/null failed");
-------------------------------------------------------------------------------
You write just:
[source,c]
-------------------------------------------------------------------------------
- fd = SAFE_OPEN("/dev/null", O_RDONLY);
+fd = SAFE_OPEN("/dev/null", O_RDONLY);
-------------------------------------------------------------------------------
-IMPORTANT: The SAFE_CLOSE() function also sets the passed file descriptor to -1
+IMPORTANT: The 'SAFE_CLOSE()' function also sets the passed file descriptor to -1
after it's successfully closed.
They can also simplify reading and writing of sysfs files, you can, for
@@ -467,7 +467,7 @@ example, do:
[source,c]
-------------------------------------------------------------------------------
- SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%lu", &pid_max);
+SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%lu", &pid_max);
-------------------------------------------------------------------------------
See 'include/tst_safe_macros.h', 'include/tst_safe_stdio.h' and
@@ -579,7 +579,7 @@ These two functions are intended for runtime kernel version detection. They
parse the output from 'uname()' and compare it to the passed values.
The return value is similar to the 'strcmp()' function, i.e. zero means equal,
-negative value means that the kernel is older than than the expected value and
+negative value means that the kernel is older than the expected value and
positive means that it's newer.
The second function 'tst_kvercmp2()' allows for specifying per-vendor table of
@@ -712,7 +712,7 @@ int main(void)
The 'tst_res()' function can be also used from binaries started by 'exec()',
the parent test process has to set the '.child_needs_reinit' flag so that the
library prepares for it and has to make sure the 'LTP_IPC_PATH' environment
-variable is passed down, then the very fist thing the program has to call in
+variable is passed down, then the very first thing the program has to call in
'main()' is 'tst_reinit()' that sets up the IPC.
1.9 Fork() and Parent-child synchronization
@@ -831,7 +831,7 @@ type defined in C99 but this one *DOES NOT* imply 'volatile' (it's just a
signal handler is either 'volatile int' or 'volatile sig_atomic_t'.
If a crash (e.g. triggered by signal SIGSEGV) is expected in testing, you
-can avoid creation of core files by calling tst_no_corefile() function.
+can avoid creation of core files by calling 'tst_no_corefile()' function.
This takes effect for process (and its children) which invoked it, unless
they subsequently modify RLIMIT_CORE.
@@ -1606,8 +1606,8 @@ as a module. If '.needs_drivers' points to a 'NULL' terminated array of kernel
module names these are all checked and the test exits with 'TCONF' on the
first missing driver.
-Since it relies on modprobe command, the check will be skipped if the command
-itself is not available on the system.
+The detection is based on reading 'modules.dep' and 'modules.builtin' files
+generated by kmod. The check is skipped on Android.
1.27 Saving & restoring /proc|sys values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1949,7 +1949,7 @@ available to the children (see the capabilities (7) manual pages).
However a lot of problems can be solved by using 'tst_cap_action(struct
tst_cap *cap)' directly which can be called at any time. This also helps if
-you wish to drop a capability at the begining of setup.
+you wish to drop a capability at the beginning of setup.
1.33 Reproducing race-conditions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2141,7 +2141,7 @@ the prefix field of file pointed by path equals to the value passed to this func
Also having a similar api pair TST_ASSERT_FILE_INT/STR(path, prefix, val) to assert
the field value of file.
-1.36 Using Control Group
+1.37 Using Control Group
~~~~~~~~~~~~~~~~~~~~~~~~
Some LTP tests need specific Control Group configurations. 'tst_cgroup.h'
@@ -2322,13 +2322,24 @@ kernel docs. Presently the LTP library does not attempt to handle most
differences in semantics. It does the minimal amount of work to make testing on
both V1 and V2 feasible.
-1.37 Require minimum numbers of CPU for a testcase
+1.38 Require minimum numbers of CPU for a testcase
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some tests require more than specific number of CPU. It can be defined with
`.min_cpus = N`.
-1.38 Test tags
+1.39 Require minimum memory or swap size for a testcase
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some tests require at least size(MB) of free RAM or Swap.
+
+To make sure that test will run only on systems with more than minimal
+required amount of RAM set `.min_mem_avail = N`.
+
+Similarily for tests that require certain amount of free Swap use
+`.min_swap_avail = N`.
+
+1.40 Test tags
~~~~~~~~~~~~~~
Test tags are name-value pairs that can hold any test metadata.
@@ -2358,22 +2369,23 @@ NOTE: We don't track all backports to stable kernel but just those which are
stable branch specific (unique), i.e. no commit in mainline. Example of
commits: c4a23c852e80, cac68d12c531.
-Glibc git commit in a regression test for a glibc bug:
+Glibc and musl git commits in a regression test for glibc and musl bugs:
[source,c]
-------------------------------------------------------------------------------
struct tst_test test = {
...
.tags = (const struct tst_tag[]) {
{"glibc-git", "574500a108be"},
+ {"musl-git", "fa4a8abd06a4"},
{}
}
};
-------------------------------------------------------------------------------
-1.39 Testing on the specific architecture
+1.41 Testing on the specific architecture
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Testcases for specific arch should be limited on that only being supported
-platform to run, we now involve a .supported_archs to achieve this feature
+platform to run, we now involve a '.supported_archs' to achieve this feature
in LTP library. All you need to run a test on the expected arch is to set
the '.supported_archs' array in the 'struct tst_test' to choose the required
arch list. e.g.
@@ -2406,11 +2418,11 @@ static struct tst_test test = {
};
-------------------------------------------------------------------------------
-1.40 Require minimum size of MemAvailable for a testcase
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Some tests require more than specific size(MB) of MemAvailable. It can be defined
-with `.min_mem_avail = N`.
+1.42 Skipping test based on system state
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test can be skipped on various conditions: on enabled SecureBoot
+('.skip_in_secureboot = 1'), lockdown ('.skip_in_lockdown = 1') or in 32-bit
+compat mode ('.skip_in_compat = 1').
2. Common problems
------------------
diff --git a/doc/c-test-tutorial-simple.txt b/doc/C-Test-Case-Tutorial.asciidoc
index 62930fdcb..07a61f4ec 100644
--- a/doc/c-test-tutorial-simple.txt
+++ b/doc/C-Test-Case-Tutorial.asciidoc
@@ -222,7 +222,7 @@ $ ./statx01
This should build the test and then run it. However, even though the test is
in the +syscalls+ directory it won't be automatically ran as part of the
_syscalls_ test group (remember +./runltp -f syscalls+ from the +README.md+?). For
-this we need to add it to the +runtest+ file. So open +runtest/statx+ and add
+this we need to add it to the +runtest+ file. So open +runtest/syscalls+ and add
the lines starting with a +++.
[source,diff]
@@ -940,7 +940,7 @@ the 'index' where you are then able to un-stage some parts before
re-committing.
You can also use +edit+ and +git commit --amend+ together to change a commit
-deep in your history, but without reseting the 'index'. The 'index' contains
+deep in your history, but without resetting the 'index'. The 'index' contains
changes which you have staged with +git add+, but not yet committed.
So now that the commit history has been cleaned up, we need to submit a patch
diff --git a/doc/network-c-api.txt b/doc/C-Test-Network-API.asciidoc
index 3bf2a1f8a..3bf2a1f8a 100644
--- a/doc/network-c-api.txt
+++ b/doc/C-Test-Network-API.asciidoc
diff --git a/doc/kvm-test-api.txt b/doc/KVM-Test-API.asciidoc
index 25b72172d..7e537afcb 100644
--- a/doc/kvm-test-api.txt
+++ b/doc/KVM-Test-API.asciidoc
@@ -194,9 +194,12 @@ previously allocated guarded buffers.
with at least `ram_size` bytes of memory. The VM instance info will be
stored in `inst`.
-- `void tst_kvm_run_instance(struct tst_kvm_instance *inst)` – Executes
- the program installed in KVM virtual machine `inst`. Any result messages
- returned by the VM will be automatically printed to controller program output.
+- `int tst_kvm_run_instance(struct tst_kvm_instance *inst, int exp_errno)` –
+ Executes the program installed in KVM virtual machine `inst`. Any result
+ messages returned by the VM will be automatically printed to controller
+ program output. Returns zero. If `exp_errno` is non-zero, the VM execution
+ syscall is allowed to fail with the `exp_errno` error code and
+ `tst_kvm_run_instance()` will return -1 instead of terminating the test.
- `void tst_kvm_destroy_instance(struct tst_kvm_instance *inst)` – Deletes
the KVM virtual machine `inst`. Note that the guarded buffers assigned
@@ -329,6 +332,10 @@ struct kvm_cpuid {
struct kvm_cregs {
unsigned long cr0, cr2, cr3, cr4;
};
+
+struct kvm_sregs {
+ uint16_t cs, ds, es, fs, gs, ss;
+};
-------------------------------------------------------------------------------
`struct page_table_entry_pae` is the page table entry structure for PAE and
@@ -343,6 +350,26 @@ Developer's Manual, Volume 3, Chapter 4 for explanation of the fields.
the known position in page table hierarchy and `entry->page_type`. Returns
zero if the `entry` does not reference any memory page.
+- `void kvm_set_segment_descriptor(struct segment_descriptor *dst, uint64_t baseaddr, uint32_t limit, unsigned int flags)` -
+ Fill the `dst` segment descriptor with given values. The maximum value
+ of `limit` is `0xfffff` (inclusive) regardless of `flags`.
+
+- `void kvm_parse_segment_descriptor(struct segment_descriptor *src, uint64_t *baseaddr, uint32_t *limit, unsigned int *flags)` -
+ Parse data in the `src` segment descriptor and copy them to variables
+ pointed to by the other arguments. Any parameter except the first one can
+ be `NULL`.
+
+- `int kvm_find_free_descriptor(const struct segment_descriptor *table, size_t size)` -
+ Find the first segment descriptor in `table` which does not have
+ the `SEGFLAG_PRESENT` bit set. The function handles double-size descriptors
+ correctly. Returns index of the first available descriptor or -1 if all
+ `size` descriptors are taken.
+
+- `unsigned int kvm_create_stack_descriptor(struct segment_descriptor *table, size_t tabsize, void *stack_base)` -
+ Convenience function for registering a stack segment descriptor. It'll
+ automatically find a free slot in `table` and fill the necessary flags.
+ The `stack_base` pointer must point to the bottom of the stack.
+
- `void kvm_get_cpuid(unsigned int eax, unsigned int ecx,
struct kvm_cpuid *buf)` – Executes the CPUID instruction with the given
`eax` and `ecx` arguments and stores the results in `buf`.
@@ -350,6 +377,9 @@ Developer's Manual, Volume 3, Chapter 4 for explanation of the fields.
- `void kvm_read_cregs(struct kvm_cregs *buf)` – Copies the current values
of control registers to `buf`.
+- `void kvm_read_sregs(struct kvm_sregs *buf)` - Copies the current values
+ of segment registers to `buf`.
+
- `uint64_t kvm_rdmsr(unsigned int msr)` – Returns the current value
of model-specific register `msr`.
@@ -363,6 +393,79 @@ Developer's Manual, Volume 3, Chapter 4 for explanation of the fields.
See Intel(R) 64 and IA-32 Architectures Software Developer's Manual
for documentation of standard and model-specific x86 registers.
+3.5 AMD SVM helper functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`#include "kvm_test.h"` +
+`#include "kvm_x86.h"` +
+`#include "kvm_x86_svm.h"`
+
+The KVM guest library provides basic helper functions for creating and running
+nested virtual machines using the AMD SVM technology.
+
+.Example code to execute nested VM
+[source,c]
+-------------------------------------------------------------------------------
+int guest_main(void)
+{
+ ...
+ return 0;
+}
+
+void main(void)
+{
+ struct kvm_svm_vcpu *vm;
+
+ kvm_init_svm();
+ vm = kvm_create_svm_vcpu(guest_main, 1);
+ kvm_svm_vmrun(vm);
+}
+-------------------------------------------------------------------------------
+
+- `int kvm_is_svm_supported(void)` - Returns non-zero value if the CPU
+ supports AMD SVM, otherwise returns 0.
+
+- `int kvm_get_svm_state(void)` - Returns non-zero value if SVM is currently
+ enabled, otherwise returns 0.
+
+- `void kvm_set_svm_state(int enabled)` - Enable or disable SVM according
+ to argument. If SVM is disabled by host or not supported, the test will exit
+ with `TCONF`.
+
+- `void kvm_init_svm(void)` - Enable and fully initialize SVM, including
+ allocating and setting up host save area VMCB. If SVM is disabled by host or
+ not supported, the test will exit with `TCONF`.
+
+- `struct kvm_vmcb *kvm_alloc_vmcb(void)` - Allocate new VMCB structure
+ with correct memory alignment and fill it with zeroes.
+
+- `void kvm_vmcb_set_intercept(struct kvm_vmcb *vmcb, unsigned int id, unsigned int state)` -
+ Set SVM intercept bit `id` to given `state`.
+
+- `void kvm_init_guest_vmcb(struct kvm_vmcb *vmcb, uint32_t asid, uint16_t ss, void *rsp, int (*guest_main)(void))` -
+ Initialize new SVM virtual machine. The `asid` parameter is the nested
+ page table ID. The `ss` and `rsp` parameters set the stack segment and stack
+ pointer values, respectively. The `guest_main` parameter sets the code entry
+ point of the virtual machine. All control registers, segment registers
+ (except stack segment register), GDTR and IDTR will be copied
+ from the current CPU state.
+
+- `struct kvm_svm_vcpu *kvm_create_svm_vcpu(int (*guest_main)(void), int alloc_stack)` -
+ Convenience function for allocating and initializing new SVM virtual CPU.
+ The `guest_main` parameter is passed to `kvm_init_guest_vmcb()`,
+ the `alloc_stack` parameter controls whether a new 8KB stack will be
+ allocated and registered in GDT. Interception will be enabled for `VMSAVE`
+ and `HLT` instructions. If you set `alloc_stack` to zero, you must configure
+ the stack segment register and stack pointer manually.
+
+- `void kvm_svm_vmrun(struct kvm_svm_vcpu *cpu)` - Start or continue execution
+ of a nested virtual machine. Beware that FPU state is not saved. Do not use
+ floating point types or values in nested guest code. Also do not use
+ `tst_res()` or `tst_brk()` functions in nested guest code.
+
+See AMD64 Architecture Programmer's Manual Volume 2 for documentation
+of the Secure Virtual Machine (SVM) technology.
+
4. KVM guest environment
------------------------
diff --git a/doc/library-api-writing-guidelines.txt b/doc/LTP-Library-API-Writing-Guidelines.asciidoc
index 3b8c1d97d..3b8c1d97d 100644
--- a/doc/library-api-writing-guidelines.txt
+++ b/doc/LTP-Library-API-Writing-Guidelines.asciidoc
diff --git a/doc/LTP-Release-Procedure.asciidoc b/doc/LTP-Release-Procedure.asciidoc
new file mode 100644
index 000000000..69c05071f
--- /dev/null
+++ b/doc/LTP-Release-Procedure.asciidoc
@@ -0,0 +1,170 @@
+LTP Release Procedure
+=====================
+
+1. Release preparations
+-----------------------
+
+The release procedure generally takes a few weeks. In the first week or two,
+patches that should go into the release are reviewed and possibly merged. These
+patches are either fixes or patches pointed out by the community.
+
+Patch review, when finished, is followed by a git freeze, which is a period
+where only fixes are pushed to the git. During that period community is
+expected to run a LTP pre-release tests, reports problems, and/or send fixes to
+the mailing list. In this period we are especially making sure that there are
+no regressions in the test results on a wide range of distributions and
+architectures.
+
+Once the stabilization period has ended the time has finally come to proceed
+with the release.
+
+2. Prepare the release notes
+----------------------------
+
+Part of the preparation is also to write the release notes, which are then
+added to the GitHub release and also sent as announcement to various mailing
+lists (see below).
+
+Have a look at https://lore.kernel.org/ltp/ZGNiQ1sMGvPU_ETp@yuki/ to get the
+idea how it should look.
+
+3. Tag the git and push changes to github
+-----------------------------------------
+
+[source,sh]
+--------------------------------------------------------------------
+cd ltp
+echo YYYYMMDD > VERSION
+git commit -S -s -m 'LTP YYYYMMDD' VERSION
+git tag -s -a YYYYMMDD -m 'LTP YYYYMMDD'
+git push origin master:master
+git push origin YYYYMMDD
+--------------------------------------------------------------------
+
+NOTE: The string YYYYMMDD should be substituted to the current date.
+
+NOTE: You can use './tools/tag-release.sh' script to have the above automated.
+ It allows you to verify the tag before pushing it and does other checks.
+
+[source,sh]
+--------------------------------------------------------------------
+$ ./tools/tag-release.sh
+===== git push =====
+new tag: 'YYYYMMDD', previous tag: '20230127'
+tag YYYYMMDD
+Tagger: Person-who-released LTP <foo@example.com>
+Date: ...
+
+LTP YYYYMMDD
+-----BEGIN PGP SIGNATURE-----
+...
+-----END PGP SIGNATURE-----
+
+commit 3ebc2dfa85c2445bb68d8c0d66e33c4da1e1b3a7
+gpg: using RSA key ...
+...
+Primary key fingerprint: ...
+Author: Person-who-released LTP <foo@example.com>
+Date: ...
+
+ LTP YYYYMMDD
+
+ Signed-off-by: Person-who-released LTP <foo@example.com>
+
+diff --git a/VERSION b/VERSION
+index af4c41fec..ae488c0e7 100644
+--- a/VERSION
++++ b/VERSION
+@@ -1 +1 @@
+-20230127
++YYYYMMDD
+
+Please check tag and signature. Proceed? [N/y]: y
+Pushing changes to upstream git. Proceed? [N/y]: y
+...
+To github.com:linux-test-project/ltp.git
+ * [new tag] YYYYMMDD -> YYYYMMDD
+--------------------------------------------------------------------
+
+4. Prepare tarballs and metadata documentation
+----------------------------------------------
+
+[source,sh]
+--------------------------------------------------------------------
+# clone already clonned git repository to new folder
+cd ..
+git clone ltp ltp-full-YYYYMMDD
+cd ltp-full-YYYYMMDD
+
+# update all submodules
+git submodule update --init
+
+# Generate configure script
+make autotools
+
+# Generate tarballs
+cd ..
+tar -cjf ltp-full-YYYYMMDD.tar.bz2 ltp-full-YYYYMMDD --exclude .git
+tar -cJf ltp-full-YYYYMMDD.tar.xz ltp-full-YYYYMMDD --exclude .git
+
+# Generate checksums
+md5 ltp-full-YYYYMMDD.tar.xz > ltp-full-YYYYMMDD.tar.xz.md5
+sha1 ltp-full-YYYYMMDD.tar.xz > ltp-full-YYYYMMDD.tar.xz.sha1
+sha256sum ltp-full-YYYYMMDD.tar.xz > ltp-full-YYYYMMDD.tar.xz.sha256
+
+# Generate metadata documentation
+./configure --with-metadata-generator=asciidoctor
+make -C metadata
+cp -v docparse/metadata.html ../metadata.YYYYMMDD.html
+--------------------------------------------------------------------
+
+NOTE: You can use './tools/create-tarballs-metadata.sh' script to have the
+ above automated. All generated files are placed in ltp-release-YYYYMMDD
+ directory.
+
+[source,sh]
+--------------------------------------------------------------------
+$ ./tools/create-tarballs-metadata.sh
+===== git clone =====
+Cloning into 'ltp-full-YYYYMMDD'...
+done.
+===== Update submodules =====
+Submodule 'tools/kirk' (https://github.com/linux-test-project/kirk.git) registered for path 'tools/kirk'
+...
+===== Generate configure script =====
+sed -n '1{s:LTP-:m4_define([LTP_VERSION],[:;s:$:]):;p;q}' VERSION > m4/ltp-version.m4
+aclocal -I m4
+...
+===== Generate tarballs =====
+===== Generate checksums =====
+===== Generate metadata documentation =====
+checking for a BSD-compatible install... /usr/bin/install -c
+...
+'docparse/metadata.html' -> '/home/foo/ltp-release-YYYYMMDD/metadata.YYYYMMDD.html'
+Generated files are in '/home/foo/ltp-release-YYYYMMDD', upload them to github
+--------------------------------------------------------------------
+
+5. Upload the generated files to GitHub
+---------------------------------------
+
+Click on https://github.com/linux-test-project/ltp/releases['Releases'] then
+switch to https://github.com/linux-test-project/ltp/tags['Tags'], then click on
+'Add release notes'. There should be 'Attach binaries ...' link at the
+bottom of the page.
+
+Don't forget to upload checksums for the tarballs and metadata documentation as well.
+
+5. Send release announcement
+----------------------------
+
+The announcement is sent to:
+
+* ltp at lists.linux.it
+* linux-kernel at vger.kernel.org
+* libc-alpha at sourceware.org
+
+CCed to:
+
+* lwn at lwn.net
+* akpm at linux-foundation.org
+* torvalds at linux-foundation.org
diff --git a/doc/Maintainer-Patch-Review-Checklist.asciidoc b/doc/Maintainer-Patch-Review-Checklist.asciidoc
new file mode 100644
index 000000000..cb9e00e8b
--- /dev/null
+++ b/doc/Maintainer-Patch-Review-Checklist.asciidoc
@@ -0,0 +1,141 @@
+# Patch Review
+
+Anyone can and should review patches. It's the only way to get good at
+patch review and for the project to scale.
+
+## Goals of patch review
+
+1. Prevent false positive test results
+2. Prevent false negative test results
+3. Keep the code as simple as possible, but no simpler
+
+## How to find clear errors
+
+A clear error is one where there is unlikely to be any argument if you
+provide evidence of it. Evidence being an error trace or logical proof
+that an error will occur in a common situation.
+
+The following are examples and may not be appropriate for all tests.
+
+* Merge the patch locally. It should apply cleanly to master.
+* Compile the patch with default and non-default configurations.
+ - Use sanitizers e.g. undefined behaviour, address.
+ - Compile on non-x86
+ - Compile on x86 with -m32
+* Use `make check`
+* Run effected tests in a VM
+ - Use single vCPU
+ - Use many vCPUs and enable NUMA
+ - Restrict RAM to < 1GB.
+* Run effected tests on an embedded device
+* Run effected tests on non-x86 machine in general
+* Run reproducers on a kernel where the bug is present
+* Run tests with "-i0"
+* Compare usage of system calls with man page descriptions
+* Compare usage of system calls with kernel code
+* Search the LTP library for existing helper functions
+
+## How to find subtle errors
+
+A subtle error is one where you can expect some argument because you
+do not have clear evidence of an error. It is best to state these as
+questions and not make assertions if possible.
+
+Although if it is a matter of style or "taste" then senior maintainers
+can assert what is correct to avoid bike shedding.
+
+* Ask what happens if there is an error, could it be debugged just
+ with the test output?
+* Are we testing undefined behavior?
+ - Could future kernel behaviour change without "breaking userland"?
+ - Does the kernel behave differently depending on hardware?
+ - Does it behave differently depending on kernel configuration?
+ - Does it behave differently depending on the compiler?
+ - Would it behave differently if the order of checks on syscall parameters
+ changed in the kernel?
+* Will it scale to tiny and huge systems?
+ - What happens if there are 100+ CPUs?
+ - What happens if each CPU core is very slow?
+ - What happens if there are 2TB of RAM?
+* Are we repeating a pattern that can be turned into a library function?
+* Is a single test trying to do too much?
+* Could multiple similar tests be merged?
+* Race conditions
+ - What happens if a process gets preempted?
+ - Could checkpoints or fuzzsync by used instead?
+ - Note, usually you can insert a sleep to prove a race condition
+ exists however finding them is hard
+* Is there a simpler way to achieve the same kernel coverage?
+
+## How to get patches merged
+
+Once you think a patch is good enough you should add your Reviewed-by
+and/or Tested-by tags. This means you will get some credit for getting
+the patch merged. Also some blame if there are problems.
+
+If you ran the test you can add the Tested-by tag. If you read the
+code or used static analysis tools on it, you can add the Reviewed-by
+tag.
+
+In addition you can expect others to review your patches and add their
+tags. This will speed up the process of getting your patches merged.
+
+## Maintainers Checklist
+
+Patchset should be tested locally and ideally also in maintainer's fork in
+GitHub Actions on GitHub.
+
+NOTE: GitHub Actions do only build testing, passing the CI means only that
+ the test compiles fine on variety of different distributions and releases.
+
+The test should be executed at least once locally and should PASS as well.
+
+Commit messages should have
+
+* Author's `Signed-off-by` tag
+* Committer's `Reviewed-by` or `Signed-off-by` tag
+* Check also mailing lists for other reviewers / testers tags, notes and failure reports
+* `Fixes: hash` if it fixes particular LTP commit
+* `Fixes: #N` if it fixes github issue number N, so it's automatically closed
+
+After patch is accepted or rejected, set correct state and archive in
+https://patchwork.ozlabs.org/project/ltp/list/[LTP patchwork instance].
+
+Also update `.github/workflows/wiki-mirror.yml` script which mirrors
+`doc/*.txt` to LTP wiki (git URL https://github.com/linux-test-project/ltp.wiki.git)
+if new wiki page is added.
+
+## New tests
+New test should
+
+* Have a record in runtest file
+* Test should work fine with more than one iteration
+ (e.g. run with `-i 100`)
+* Run with `-i 0` to check that setup and cleanup are coded properly (no test is being run)
+* Have a brief description
+* License: the default license for new tests is GPL v2 or later, use
+ GPL-2.0-or-later; the licence for test (e.g. GPL-2.0) should not change
+ unless test is completely rewritten
+* Old copyrights should be kept unless test is completely rewritten
+
+### C tests
+* Use new https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#22-writing-a-test-in-c[C API]
+* Test binaries are added into corresponding `.gitignore` files
+* Check coding style with `make check`
+ (more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#21-c-coding-style[C coding style])
+* Docparse documentation
+* If a test is a regression test it should include tags
+ (more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#2238-test-tags[Test tags])
+* When rewriting old tests, https://en.wikipedia.org/wiki/%CE%9CClinux[uClinux]
+ support should be removed (project has been discontinued).
+ E.g. remove `#ifdef UCLINUX`, replace `FORK_OR_VFORK()` with simple `fork()` or `SAFE_FORK()`.
+
+### Shell tests
+* Use new https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#23-writing-a-testcase-in-shell[shell API]
+* Check coding style with `make check`
+ (more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#132-shell-coding-style[Shell coding style])
+* If a test is a regression test it should include related kernel or glibc commits as a comment
+
+## LTP library
+For patchset touching library please check also
+https://github.com/linux-test-project/ltp/wiki/LTP-Library-API-Writing-Guidelines[LTP Library API Writing Guidelines].
diff --git a/doc/shell-test-api.txt b/doc/Shell-Test-API.asciidoc
index e5c918660..4cf630dab 100644
--- a/doc/shell-test-api.txt
+++ b/doc/Shell-Test-API.asciidoc
@@ -26,7 +26,6 @@ WARNING: All identifiers starting with 'TST_' or 'tst_' are reserved for the
# This is a basic test for true shell builtin
TST_TESTFUNC=do_test
-. tst_test.sh
do_test()
{
@@ -79,7 +78,6 @@ not trigger calling it.
TST_TESTFUNC=test
TST_CNT=2
-. tst_test.sh
test1()
{
@@ -110,7 +108,6 @@ found they are executed one by one. The test number is passed to it in the '$1'.
TST_TESTFUNC=do_test
TST_CNT=2
-. tst_test.sh
do_test()
{
@@ -141,7 +138,6 @@ to it in the '$1'.
TST_TESTFUNC=do_test
TST_TEST_DATA="foo:bar:d dd"
TST_TEST_DATA_IFS=":"
-. tst_test.sh
do_test()
{
@@ -168,7 +164,6 @@ It's possible to pass data for function with '$TST_TEST_DATA'. Optional
TST_TESTFUNC=do_test
TST_CNT=2
TST_TEST_DATA="foo bar"
-. tst_test.sh
do_test()
{
@@ -285,7 +280,6 @@ as it doesn't exit (it issues 'tst_res TCONF'). Expected usage is:
#!/bin/sh
TST_TESTFUNC=do_test
-. tst_test.sh
do_test()
{
@@ -325,8 +319,6 @@ TST_USAGE=usage
TST_PARSE_ARGS=parse_args
TST_TESTFUNC=do_test
-. tst_test.sh
-
ALTERNATIVE=0
MODE="foo"
@@ -378,8 +370,6 @@ TST_POS_ARGS=3
TST_USAGE=usage
TST_TESTFUNC=do_test
-. tst_test.sh
-
usage()
{
cat << EOF
@@ -831,3 +821,8 @@ TST_NEEDS_KCONFIGS="CONFIG_EXT4_FS, CONFIG_QUOTACTL=y"
. tst_test.sh
-------------------------------------------------------------------------------
+
+1.8 Skipping test based on system state
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test can be skipped on various conditions: on enabled SecureBoot
+('TST_SKIP_IN_SECUREBOOT=1'), lockdown ('TST_SKIP_IN_LOCKDOWN=1').
diff --git a/doc/supported-kernel-libc-versions.txt b/doc/Supported-kernel,-libc,-toolchain-versions.asciidoc
index 6b9970872..e3d9cd92f 100644
--- a/doc/supported-kernel-libc-versions.txt
+++ b/doc/Supported-kernel,-libc,-toolchain-versions.asciidoc
@@ -62,7 +62,7 @@ Minimal supported kernel version is 3.10.
[align="center",options="header"]
|==================================
| Libc | Note
-| https://www.gnu.org/software/libc/[GNU C Library (glibc)] | Targetted libc, tested both compilation and actual test results.
+| https://www.gnu.org/software/libc/[GNU C Library (glibc)] | Targeted libc, tested both compilation and actual test results.
| https://uclibc-ng.org/[uClibc-ng] | Although not being tested it should work as well as it attempt to maintain a glibc compatible interface.
| https://www.uclibc.org/[uClibc] | Older https://www.uclibc.org/[uClibc] might have problems.
| https://musl.libc.org/[musl] | Not yet fully supported (see
diff --git a/doc/test-writing-guidelines.txt b/doc/Test-Writing-Guidelines.asciidoc
index b83a6fdb6..0db852ae6 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/Test-Writing-Guidelines.asciidoc
@@ -370,6 +370,7 @@ https://github.com/linux-test-project/ltp/wiki/Shell-Test-API[Shell Test API].
| '.min_kver' | 'TST_MIN_KVER'
| '.min_mem_avail' | not applicable
| '.mnt_flags' | 'TST_MNT_PARAMS'
+| '.min_swap_avail' | not applicable
| '.mntpoint', '.mnt_data' | 'TST_MNTPOINT'
| '.mount_device' | 'TST_MOUNT_DEVICE'
| '.needs_cgroup_ctrls' | –
@@ -392,7 +393,8 @@ https://github.com/linux-test-project/ltp/wiki/Shell-Test-API[Shell Test API].
| '.setup' | 'TST_SETUP'
| '.skip_filesystems' | 'TST_SKIP_FILESYSTEMS'
| '.skip_in_compat' | –
-| '.skip_in_lockdown' | –
+| '.skip_in_lockdown' | 'TST_SKIP_IN_LOCKDOWN'
+| '.skip_in_secureboot' | 'TST_SKIP_IN_SECUREBOOT'
| '.supported_archs' | not applicable
| '.tags' | –
| '.taint_check' | –
diff --git a/doc/user-guide.txt b/doc/User-Guidelines.asciidoc
index 8f2418df0..8f2418df0 100644
--- a/doc/user-guide.txt
+++ b/doc/User-Guidelines.asciidoc
diff --git a/doc/maintainer-patch-review-checklist.txt b/doc/maintainer-patch-review-checklist.txt
deleted file mode 100644
index 5d3c6886a..000000000
--- a/doc/maintainer-patch-review-checklist.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-# Maintainer Patch Review Checklist
-
-Patchset should be tested locally and ideally also in maintainer's fork in
-GitHub Actions on GitHub.
-
-NOTE: Travis does only build testing, passing the CI means only that the
- test compiles fine on variety of different distributions and
- releases.
-
-The test should be executed at least once locally and should PASS as well.
-
-Commit messages should have
-
-* Author's `Signed-off-by` tag
-* Committer's `Reviewed-by` or `Signed-off-by` tag
-* Check also mailing lists for other reviewers / testers tags, notes and failure reports
-* `Fixes: hash` if it fixes particular LTP commit
-* `Fixes: #N` if it fixes github issue number N, so it's automatically closed
-
-After patch is accepted or rejected, set correct state and archive in
-https://patchwork.ozlabs.org/project/ltp/list/[LTP patchwork instance].
-
-Also update `.github/workflows/wiki-mirror.yml` script which mirrors
-`doc/*.txt` to LTP wiki (git URL https://github.com/linux-test-project/ltp.wiki.git)
-if new wiki page is added.
-
-## New tests
-New test should
-
-* Have a record in runtest file
-* Test should work fine with more than one iteration
- (e.g. run with `-i 100`)
-* Run with `-i 0` to check that setup and cleanup are coded properly (no test is being run)
-* Have a brief description
-* License: the default license for new tests is GPL v2 or later, use
- GPL-2.0-or-later; the licence for test (e.g. GPL-2.0) should not change
- unless test is completely rewritten
-* Old copyrights should be kept unless test is completely rewritten
-
-### C tests
-* Use new https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#22-writing-a-test-in-c[C API]
-* Test binaries are added into corresponding '.gitignore' files
-* Check coding style with `make check`
- (more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#21-c-coding-style[C coding style])
-* Docparse documentation
-* If a test is a regression test it should include tags
- (more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#2238-test-tags[Test tags])
-* When rewriting old tests, https://en.wikipedia.org/wiki/%CE%9CClinux[uClinux]
- support should be removed (project has been discontinued).
- E.g. remove `#ifdef UCLINUX`, replace `FORK_OR_VFORK()` with simple `fork()` or `SAFE_FORK()`.
-
-### Shell tests
-* Use new https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#23-writing-a-testcase-in-shell[shell API]
-* Check coding style with `make check`
- (more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#132-shell-coding-style[Shell coding style])
-* If a test is a regression test it should include related kernel or glibc commits as a comment
-
-## LTP library
-For patchset touching library please check also
-https://github.com/linux-test-project/ltp/wiki/LTP-Library-API-Writing-Guidelines[LTP Library API Writing Guidelines].
diff --git a/doc/man1/ltp-pan.1 b/doc/man1/ltp-pan.1
index 3f6ddb925..5ffa57dba 100644
--- a/doc/man1/ltp-pan.1
+++ b/doc/man1/ltp-pan.1
@@ -161,7 +161,7 @@ signal is SIGUSR1 then ltp-pan will behave as if \fI-y\fP had not been specified
.SH EXAMPLES
-In practice, the ZOO environment variable is generally prefered over the
+In practice, the ZOO environment variable is generally preferred over the
\fI-a\fP option. All examples assume this is being set.
The following creates a ltp-pan named "ex1" with an active file in /tmp/active.
diff --git a/doc/man3/parse_ranges.3 b/doc/man3/parse_ranges.3
index 93bb412e3..d92e001f1 100644
--- a/doc/man3/parse_ranges.3
+++ b/doc/man3/parse_ranges.3
@@ -95,7 +95,7 @@ The function should return -1 if str cannot be parsed
into an integer, or >= 0 if it was successfully
parsed. The resulting integer will be stored in
*val. If parse_func is NULL, parse_ranges will parse
-the tokens in a manner consistent with the the sscanf %i format.
+the tokens in a manner consistent with the sscanf %i format.
.TP 1i
\fIrange_ptr\fP
A user-supplied char **, which will be set to point
diff --git a/doc/namespaces-helper-tools.txt b/doc/namespaces-helper-tools.txt
index 6990e0155..b911dd6cc 100644
--- a/doc/namespaces-helper-tools.txt
+++ b/doc/namespaces-helper-tools.txt
@@ -8,18 +8,16 @@ LTP namespaces helper tools
LTP provides helper tools for creating and working with namespaces. These are
located in ltp/testcases/kernel/containers/share directory and include:
-* ns_create
+* tst_ns_create
** creates a child process in the new specified namespace(s)
** child is then daemonized and is running in the background
** PID of the daemonized child process is printed on the stdout
** the new namespace(s) is(are) maintained by the daemonized child process
** namespace(s) can be removed by killing the daemonized process
-* setns_check
-** check for setns() availability, should be called before using ns_exec
-* ns_exec
+* tst_ns_exec
** enters the namespace(s) of a process specified by a PID
** then executes the indicated program inside that namespace(s)
-* ns_ifmove
+* tst_ns_ifmove
** moves a network interface to the namespace of a process specified by a PID
Purpose of these helper tools is the ability to execute test cases utilizing
@@ -36,18 +34,18 @@ The following code shows how test cases can use the namespaces helper tools:
-------------------------------------------------------------------------------
# Creates a new network and ipc namespace and stores the PID of the daemonized
# process inside that namespace into variable myns
-myns=$(ns_create net,ipc)
+myns=$(tst_ns_create net,ipc)
ip link add veth0 type veth peer name veth1
# Executes command 'ip a' inside the namespace specified by PID in myns variable
-ns_exec $myns net,ipc ip a
+tst_ns_exec $myns net,ipc ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# Moves interface veth1 into the namespace specified by PID in myns variable
-ns_ifmove veth1 $myns
-ns_exec $myns net,ipc ip a
+tst_ns_ifmove veth1 $myns
+tst_ns_exec $myns net,ipc ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: veth1: <BROADCAST> mtu 1500 qdisc noop state DOWN qlen 1000
diff --git a/docparse/README.md b/docparse/README.md
index db156e64d..9ccfa44af 100644
--- a/docparse/README.md
+++ b/docparse/README.md
@@ -48,7 +48,7 @@ given test, as obviously we cannot run two tests that monopolize the same
resource. In some cases we would also need to partition the system resource
accordingly, e.g. if we have two memory stress tests running at the same time
we will need to cap each of these tests on half of the available memory, or
-make sure that sum of the memory used by these two tests is not greater an
+make sure that sum of the memory used by these two tests is not greater than
available memory.
Examples of such tests are:
diff --git a/docparse/testinfo.pl b/docparse/testinfo.pl
index 67e435d79..78433c40a 100755
--- a/docparse/testinfo.pl
+++ b/docparse/testinfo.pl
@@ -13,12 +13,13 @@ use File::Basename qw(dirname);
use constant OUTDIR => dirname(abs_path($0));
# tags which expect git tree, also need constant for URL
-our @TAGS_GIT = ("linux-git", "linux-stable-git", "glibc-git");
+our @TAGS_GIT = ("linux-git", "linux-stable-git", "glibc-git", "musl-git");
# tags should map these in lib/tst_test.c
use constant LINUX_GIT_URL => "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=";
use constant LINUX_STABLE_GIT_URL => "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=";
use constant GLIBC_GIT_URL => "https://sourceware.org/git/?p=glibc.git;a=commit;h=";
+use constant MUSL_GIT_URL => "https://git.musl-libc.org/cgit/musl/commit/src/linux/clone.c?id=";
use constant CVE_DB_URL => "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-";
sub load_json
diff --git a/execltp.in b/execltp.in
deleted file mode 100755
index 4b647cd17..000000000
--- a/execltp.in
+++ /dev/null
@@ -1,474 +0,0 @@
-#!/usr/bin/env python3
-"""
- An LTP [execution and] parsing wrapper.
-
- Used as a second layer for ease-of-use with users as many developers
- complain about complexity involved with trying to use LTP in my
- organization -_-.
-
- Copyright (C) 2009-2012, Ngie Cooper
-
- 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, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-"""
-
-
-from optparse import OptionGroup, OptionParser
-import os
-import re
-import sys
-
-
-class ResultsParseException(Exception):
- """ Extended class for parsing LTP results. """
-
-
-def parse_ltp_results(exec_log, output_log, verbose=0):
- """Function for parsing LTP results.
-
- 1. The exec log is the log with the results in summary form.
-
- And now a note from our sponsors about exec logs...
-
- startup='Thu Oct 1 06:42:07 2009'
- tag=abort01 stime=1254379327 dur=2 exit=exited stat=0 core=no cu=0 cs=16
- tag=accept01 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=1 cs=0
- tag=access01 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=0 cs=0
- tag=access02 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=0 cs=0
- tag=access03 stime=1254379329 dur=1 exit=exited stat=0 core=no cu=0 cs=1
-
- [...]
-
- a. tag is the test tag name.
- b. stime is the system time at the start of the exec.
- c. dur is the total duration of the test.
- d. exit tells you what the result was. Valid values are:
- - exited
- - signaled
- - stopped
- - unknown
- See run_child in pan.c.
- e. stat is the exit status.
- f. core answers the question: `did I dump core?'.
- g. cu is the cutime (cumulative user time).
- h. cs is the cstime (cumulative system time).
-
- 2. The output log is the log with all of the terse results.
- 3. verbose tells us whether or not we need to include the passed results.
- """
-
- if not os.access(exec_log, os.R_OK):
- raise ResultsParseException("Exec log - %s - specified doesn't exist"
- % exec_log)
- elif 1 < verbose and not os.access(output_log, os.R_OK):
- # Need the output log for context to the end user.
- raise ResultsParseException("Output log - %s - specified doesn't exist"
- % output_log)
-
- context = None
-
- failed = []
- passed = 0
-
- if 2 <= verbose:
- passed = []
-
- target_vals = ('exited', '0', 'no')
-
- fd = open(exec_log, 'r')
-
- try:
- content = fd.read()
- matches = re.finditer('tag=(?P<tag>\w+).+exit=(?P<exit>\w+) '
- 'stat=(?P<stat>\d+) core=(?P<core>\w+)', content)
- finally:
- content = None
- fd.close()
-
- if not matches:
- raise ResultsParseException("No parseable results were found in the "
- "exec log - `%s'." % exec_log)
-
- for match in matches:
-
- if ((match.group('exit'), match.group('stat'), match.group('core')) !=
- target_vals):
- failed.append(match.group('tag'))
- elif 2 <= verbose:
- passed.append(match.group('tag'))
- else:
- passed += 1
-
- # Save memory on large files because lists can eat up a fair amount of
- # memory.
- matches = None
-
- if 1 <= verbose:
-
- context = {}
-
- search_tags = failed[:]
-
- if 2 <= verbose:
- search_tags += passed
-
- search_tags.sort()
-
- fd = open(output_log, 'r')
-
- try:
-
- line_iterator = getattr(fd, 'xreadlines', getattr(fd, 'readlines'))
-
- end_output = '<<<execution_status>>>'
- output_start = '<<<test_output>>>'
-
- tag_re = re.compile('tag=(\w+)')
-
- grab_output = False
-
- local_context = ''
-
- search_tag = None
-
- try:
-
- while True:
-
- line = next(line_iterator)
-
- if line.startswith(end_output):
-
- if search_tag:
- context[search_tag] = local_context
-
- grab_output = False
- local_context = ''
- search_tag = None
-
- if not search_tag:
-
- while True:
-
- line = next(line_iterator)
-
- match = tag_re.match(line)
-
- if match and match.group(1) in search_tags:
- search_tag = match.group(1)
- break
-
- elif line.startswith(output_start):
- grab_output = True
- elif grab_output:
- local_context += line
-
- except StopIteration:
- pass
-
- for k in list(context.keys()):
- if k not in search_tags:
- raise ResultsParseException('Leftover token in search '
- 'keys: %s' % k)
-
- except Exception as exc:
- # XXX (garrcoop): change from Exception to soft error and print
- # out warning with logging module.
- raise ResultsParseException('Encountered exception reading output '
- 'for context: %s' % str(exc))
- finally:
- fd.close()
-
- return failed, passed, context
-
-
-def determine_context(output_log, testsuite, test_set, context):
- """Return a set of context values mapping test_set -> context."""
-
- test_set_context = {}
-
- for test in test_set:
-
- if test in context:
- test_context = context[test]
- del context[test]
- else:
- test_context = ('Could not determine context for %s; please see '
- 'output log - %s' % (test, output_log))
-
- test_set_context['%s : %s' % (testsuite, test)] = test_context
-
- return test_set_context
-
-
-def print_context(output_dest, header, testsuite_context):
- """Print out testsuite_context to output_dest, heading it up with
- header.
- """
-
- output_dest.write('\n'.join(['', '=' * 40, header, '-' * 40, '']))
-
- for test, context in list(testsuite_context.items()):
- output_dest.write('<output test="%s">\n%s\n</output>\n' %
- (test, context.strip()))
-
-
-def main():
- """main"""
-
- parser = OptionParser(prog=os.path.basename(sys.argv[0]),
- usage='usage: %prog [options] test ...',
- version='0.0.2')
-
- ltpdir = os.getenv('LTPROOT', '@prefix@')
-
- parser.add_option('-l', '--ltp-dir', dest='ltp_dir',
- default=ltpdir, help='LTP directory [default: %default]')
- parser.add_option('-L', '--log-dir', dest='log_dir',
- default=None,
- help=('directory for [storing and] retrieving logs '
- '[default: %s/output]' % ltpdir),
- metavar='DIR')
- parser.add_option('-p', '--postprocess-only', dest='postprocess_only',
- default=False, action='store_true',
- help=("Don't execute runltp; just postprocess logs "
- "[default: %default]."))
- parser.add_option('-o', '--output-file', dest='output_file',
- default=None,
- help='File to output results')
- parser.add_option('-r', '--runltp-opts', dest='runltp_opts',
- default='',
- help=('options to pass directly to runltp (will '
- 'suppress -q).'))
-
- group = OptionGroup(parser, 'Logging',
- 'If --summary-mode is 0, then the summary output is '
- 'suppressed. '
- 'If --summary-mode is 1 [the default], then summary '
- 'output will be displayed for test execution'
- 'If --summary-mode is 2, then summary output will be '
- 'provided on a per-test suite basis. If only '
- 'one test suite is specified, this has the same net '
- "effect as `--summary-mode 1'"
- 'If --verbose is specified once, prints out failed '
- 'test information with additional context. '
- 'If --verbose is specified twice, prints out the '
- 'failed and passed test context, as well as the '
- 'summary.')
-
- parser.add_option('-s', '--summary-mode', dest='summary_mode', default=1,
- type='int',
- help='See Logging.')
-
- parser.add_option('-v', '--verbose', dest='verbose', default=0,
- action='count',
- help=('Increases context verbosity from tests. See '
- 'Verbosity for more details.'))
- parser.add_option_group(group)
-
- group = OptionGroup(parser, 'Copyright',
- '%(prog)s version %(version)s, Copyright (C) '
- '2009-2012, Ngie Cooper %(prog)s comes with '
- 'ABSOLUTELY NO WARRANTY; '
- 'This is free software, and you are welcome to '
- 'redistribute it under certain conditions (See the '
- 'license tort in %(file)s for more details).'
- % { 'file' : os.path.abspath(__file__),
- 'prog' : parser.prog,
- 'version' : parser.version })
-
- parser.add_option_group(group)
-
- opts, args = parser.parse_args()
-
- # Remove -q from the opts string, as long as it's a standalone option.
- runltp_opts = re.sub('^((?<!\S)+\-q\s+|\-q|\s+\-q(?!\S))$', '',
- opts.runltp_opts)
-
- if not opts.log_dir:
- opts.log_dir = os.path.join(opts.ltp_dir, 'output')
-
- if not opts.summary_mode and not opts.verbose:
- parser.error('You cannot suppress summary output and disable '
- 'verbosity.')
- elif opts.summary_mode not in list(range(3)):
- parser.error('--summary-mode must be a value between 0 and 2.')
-
- if len(args) == 0:
- # Default to scenarios also used by runltp.
- fd = open(os.path.join(ltpdir, 'scenario_groups/default'), 'r')
- try:
- args = [l.strip() for l in fd.readlines()]
- finally:
- fd.close()
-
- if opts.output_file:
-
- output_dir = os.path.dirname(opts.output_file)
-
- if output_dir:
- # Not cwd; let's check to make sure that the directory does or
- # does not exist.
-
- if not os.path.exists(output_dir):
- # We need to make the directory.
- os.makedirs(os.path.dirname(opts.output_file))
- elif not os.path.isdir(os.path.abspath(output_dir)):
- # Path exists, but isn't a file. Oops!
- parser.error('Dirname for path specified - %s - is not valid'
- % output_dir)
-
- else:
- # Current path (cwd)
- opts.output_file = os.path.join(os.getcwd(), opts.output_file)
-
- output_dest = open(opts.output_file, 'w')
-
- else:
-
- output_dest = sys.stdout
-
- try:
-
- failed_context = {}
- passed_context = {}
-
- failed_count = 0
- passed_count = 0
-
- if opts.summary_mode == 2 and len(args) == 1:
- opts.summary_mode = 1
-
- for testsuite in args:
-
- # Iterate over the provided test list
-
- context = {}
- exec_log = os.path.join(opts.log_dir, '%s-exec.log' % testsuite)
- output_log = os.path.join(opts.log_dir, ('%s-output.log'
- % testsuite))
-
- failed_subset = {}
-
- runtest_file = os.path.join(opts.ltp_dir, 'runtest', testsuite)
-
- if not opts.postprocess_only:
-
- for log in [exec_log, output_log]:
- if os.path.isfile(log):
- os.remove(log)
-
- if not os.access(runtest_file, os.R_OK):
- output_dest.write("%s doesn't exist; skipping "
- "test\n" % runtest_file)
- continue
-
- os.system(' '.join([os.path.join(opts.ltp_dir, 'runltp'),
- runltp_opts, '-f', testsuite,
- '-l', exec_log, '-o', output_log]))
-
- try:
-
- failed_subset, passed_css, context = \
- parse_ltp_results(exec_log, output_log,
- verbose=opts.verbose)
-
- except ResultsParseException as rpe:
- output_dest.write('Error encountered when parsing results for '
- 'test - %s: %s\n' % (testsuite, str(rpe)))
- continue
-
- failed_count += len(failed_subset)
-
- failed_subset_context = {}
- passed_subset_context = {}
-
- if opts.verbose:
- failed_subset_context = determine_context(output_log,
- testsuite,
- failed_subset,
- context)
- if type(passed_css) == list:
-
- passed_count += len(passed_css)
-
- if opts.verbose == 2:
- passed_subset_context = determine_context(output_log,
- testsuite,
- passed_css,
- context)
-
- else:
-
- passed_count += passed_css
-
- if opts.summary_mode == 1:
-
- failed_context.update(failed_subset_context)
- passed_context.update(passed_subset_context)
-
- else:
-
- if 1 <= opts.verbose:
- # Print out failed testcases.
- print_context(output_dest,
- 'FAILED TESTCASES for %s' % testsuite,
- failed_subset_context)
-
- if opts.verbose == 2:
- # Print out passed testcases with context.
- print_context(output_dest,
- 'PASSED TESTCASES for %s' % testsuite,
- passed_subset_context)
-
- if opts.summary_mode == 2:
- output_dest.write("""
-========================================
-SUMMARY for: %s
-----------------------------------------
-PASS - %d
-FAIL - %d
-----------------------------------------
-""" % (testsuite, passed_count, len(failed_subset)))
-
- if opts.summary_mode == 1:
-
- # Print out overall results.
-
- if 1 <= opts.verbose:
- # Print out failed testcases with context.
- print_context(output_dest, "FAILED TESTCASES", failed_context)
-
- if opts.verbose == 2:
- # Print out passed testcases with context.
- print_context(output_dest, "PASSED TESTCASES", passed_context)
-
- output_dest.write("""
-========================================
-SUMMARY for tests:
-%s
-----------------------------------------
-PASS - %d
-FAIL - %d
-----------------------------------------
-""" % (' '.join(args), passed_count, failed_count))
-
- finally:
-
- if output_dest != sys.stdout:
-
- output_dest.close()
-
-if __name__ == '__main__':
- main()
diff --git a/gen.bp b/gen.bp
index 7a0a9f585..bb510d14f 100644
--- a/gen.bp
+++ b/gen.bp
@@ -1000,6 +1000,18 @@ cc_test {
}
cc_test {
+ name: "ltp_cgroup_core03",
+ stem: "cgroup_core03",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/controllers/cgroup/cgroup_core03.c"],
+ local_include_dirs: [
+ "include/old",
+ "testcases/kernel/controllers/libcontrollers",
+ ],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_cgroup_fj_proc",
stem: "cgroup_fj_proc",
defaults: ["ltp_test_defaults"],
@@ -1502,6 +1514,15 @@ cc_test {
}
cc_test {
+ name: "ltp_clone303",
+ stem: "clone303",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/clone3/clone303.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_close01",
stem: "close01",
defaults: ["ltp_test_defaults"],
@@ -2748,6 +2769,33 @@ cc_test {
}
cc_test {
+ name: "ltp_epoll_wait05",
+ stem: "epoll_wait05",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/epoll_wait/epoll_wait05.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_epoll_wait06",
+ stem: "epoll_wait06",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/epoll_wait/epoll_wait06.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_epoll_wait07",
+ stem: "epoll_wait07",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/epoll_wait/epoll_wait07.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_event_generator",
stem: "event_generator",
defaults: ["ltp_test_defaults"],
@@ -2766,6 +2814,51 @@ cc_test {
}
cc_test {
+ name: "ltp_eventfd02",
+ stem: "eventfd02",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/eventfd/eventfd02.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_eventfd03",
+ stem: "eventfd03",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/eventfd/eventfd03.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_eventfd04",
+ stem: "eventfd04",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/eventfd/eventfd04.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_eventfd05",
+ stem: "eventfd05",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/eventfd/eventfd05.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_eventfd06",
+ stem: "eventfd06",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/eventfd/eventfd06.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_eventfd2_01",
stem: "eventfd2_01",
defaults: ["ltp_test_defaults"],
@@ -3087,6 +3180,33 @@ cc_test {
}
cc_test {
+ name: "ltp_faccessat02",
+ stem: "faccessat02",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/faccessat/faccessat02.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_faccessat201",
+ stem: "faccessat201",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/faccessat2/faccessat201.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_faccessat202",
+ stem: "faccessat202",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/faccessat2/faccessat202.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_fallocate01",
stem: "fallocate01",
defaults: ["ltp_test_defaults"],
@@ -3770,38 +3890,6 @@ cc_test {
}
cc_test {
- name: "ltp_fcntl06",
- stem: "fcntl06",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/syscalls/fcntl/fcntl06.c"],
- cflags: ["-D_GNU_SOURCE"],
- local_include_dirs: [
- "include/old",
- "testcases/kernel/syscalls/fcntl",
- "testcases/kernel/syscalls/utils",
- ],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_fcntl06_64",
- stem: "fcntl06_64",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/syscalls/fcntl/fcntl06.c"],
- cflags: [
- "-DTST_USE_NEWER64_SYSCALL=1",
- "-D_FILE_OFFSET_BITS=64",
- "-D_GNU_SOURCE",
- ],
- local_include_dirs: [
- "include/old",
- "testcases/kernel/syscalls/fcntl",
- "testcases/kernel/syscalls/utils",
- ],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
name: "ltp_fcntl07",
stem: "fcntl07",
defaults: ["ltp_test_defaults"],
@@ -5266,6 +5354,15 @@ cc_test {
}
cc_test {
+ name: "ltp_fsconfig03",
+ stem: "fsconfig03",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/fsconfig/fsconfig03.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_fsetxattr01",
stem: "fsetxattr01",
defaults: ["ltp_test_defaults"],
@@ -7679,6 +7776,25 @@ cc_test {
}
cc_test {
+ name: "ltp_hugemmap32",
+ stem: "hugemmap32",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/mem/hugetlb/hugemmap/hugemmap32.c"],
+ local_include_dirs: [
+ "include/old",
+ "testcases/kernel/include",
+ "testcases/kernel/mem/hugetlb/lib",
+ "testcases/kernel/mem/include",
+ ],
+ static_libs: [
+ "libltp_hugetlb",
+ "libltp_kerntest",
+ "libltp_ltp",
+ "libltp_mem",
+ ],
+}
+
+cc_test {
name: "ltp_icmp_rate_limit01",
stem: "icmp_rate_limit01",
defaults: ["ltp_test_defaults"],
@@ -9223,6 +9339,15 @@ cc_test {
}
cc_test {
+ name: "ltp_madvise11",
+ stem: "madvise11",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/madvise/madvise11.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_mallinfo01",
stem: "mallinfo01",
defaults: ["ltp_test_defaults"],
@@ -10037,15 +10162,6 @@ cc_test {
}
cc_test {
- name: "ltp_mmap07",
- stem: "mmap07",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/syscalls/mmap/mmap07.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
name: "ltp_mmap08",
stem: "mmap08",
defaults: ["ltp_test_defaults"],
@@ -10172,6 +10288,15 @@ cc_test {
}
cc_test {
+ name: "ltp_mmap20",
+ stem: "mmap20",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/mmap/mmap20.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_mmap3",
stem: "mmap3",
defaults: ["ltp_test_defaults"],
@@ -10390,6 +10515,16 @@ cc_test {
}
cc_test {
+ name: "ltp_mount07",
+ stem: "mount07",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/mount/mount07.c"],
+ cflags: ["-D_GNU_SOURCE"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_mount_setattr01",
stem: "mount_setattr01",
defaults: ["ltp_test_defaults"],
@@ -10662,6 +10797,15 @@ cc_test {
}
cc_test {
+ name: "ltp_mprotect05",
+ stem: "mprotect05",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/mprotect/mprotect05.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_mremap01",
stem: "mremap01",
defaults: ["ltp_test_defaults"],
@@ -10698,6 +10842,15 @@ cc_test {
}
cc_test {
+ name: "ltp_mremap06",
+ stem: "mremap06",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/mremap/mremap06.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_msgget05",
stem: "msgget05",
defaults: ["ltp_test_defaults"],
@@ -10863,15 +11016,6 @@ cc_test {
}
cc_test {
- name: "ltp_newns",
- stem: "newns",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/newns.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
name: "ltp_newuname01",
stem: "newuname01",
defaults: ["ltp_test_defaults"],
@@ -11887,6 +12031,15 @@ cc_test {
}
cc_test {
+ name: "ltp_pipe14",
+ stem: "pipe14",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/pipe/pipe14.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_pipe2_01",
stem: "pipe2_01",
defaults: ["ltp_test_defaults"],
@@ -12455,6 +12608,15 @@ cc_test {
}
cc_test {
+ name: "ltp_process_madvise01",
+ stem: "process_madvise01",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/process_madvise/process_madvise01.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_process_vm01",
stem: "process_vm01",
defaults: ["ltp_test_defaults"],
@@ -15003,33 +15165,6 @@ cc_test {
}
cc_test {
- name: "ltp_setgroups04",
- stem: "setgroups04",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/syscalls/setgroups/setgroups04.c"],
- local_include_dirs: [
- "include/old",
- "testcases/kernel/syscalls/setgroups",
- "testcases/kernel/syscalls/utils",
- ],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_setgroups04_16",
- stem: "setgroups04_16",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/syscalls/setgroups/setgroups04.c"],
- cflags: ["-DTST_USE_COMPAT16_SYSCALL=1"],
- local_include_dirs: [
- "include/old",
- "testcases/kernel/syscalls/setgroups",
- "testcases/kernel/syscalls/utils",
- ],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
name: "ltp_sethostname01",
stem: "sethostname01",
defaults: ["ltp_test_defaults"],
@@ -16372,6 +16507,15 @@ cc_test {
}
cc_test {
+ name: "ltp_starvation",
+ stem: "starvation",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/sched/cfs-scheduler/starvation.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_stat01",
stem: "stat01",
defaults: ["ltp_test_defaults"],
@@ -16633,6 +16777,33 @@ cc_test {
}
cc_test {
+ name: "ltp_statx10",
+ stem: "statx10",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/statx/statx10.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_statx11",
+ stem: "statx11",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/statx/statx11.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_statx12",
+ stem: "statx12",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/syscalls/statx/statx12.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_stream01",
stem: "stream01",
defaults: ["ltp_test_defaults"],
@@ -17055,6 +17226,16 @@ cc_test {
}
cc_test {
+ name: "ltp_tcindex01",
+ stem: "tcindex01",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/cve/tcindex01.c"],
+ cflags: ["-D_GNU_SOURCE"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_tee01",
stem: "tee01",
defaults: ["ltp_test_defaults"],
@@ -20372,6 +20553,14 @@ sh_test {
}
sh_test {
+ name: "ltp_testcases_bin_nfs08.sh",
+ src: "testcases/network/nfs/nfs_stress/nfs08.sh",
+ sub_dir: "ltp/testcases/bin",
+ filename: "nfs08.sh",
+ compile_multilib: "both",
+}
+
+sh_test {
name: "ltp_testcases_bin_nfs_lib.sh",
src: "testcases/network/nfs/nfs_stress/nfs_lib.sh",
sub_dir: "ltp/testcases/bin",
@@ -23532,14 +23721,6 @@ sh_test {
}
sh_test {
- name: "ltp_testcases_bin_testall.sh",
- src: "testcases/kernel/security/tomoyo/testall.sh",
- sub_dir: "ltp/testcases/bin",
- filename: "testall.sh",
- compile_multilib: "both",
-}
-
-sh_test {
name: "ltp_testcases_bin_tracepath01.sh",
src: "testcases/network/tcp_cmds/tracepath/tracepath01.sh",
sub_dir: "ltp/testcases/bin",
@@ -24607,78 +24788,6 @@ cc_test {
}
cc_test {
- name: "ltp_tomoyo_accept_test",
- stem: "tomoyo_accept_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_accept_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_tomoyo_file_test",
- stem: "tomoyo_file_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_file_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_tomoyo_filesystem_test",
- stem: "tomoyo_filesystem_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_filesystem_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_tomoyo_new_file_test",
- stem: "tomoyo_new_file_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_new_file_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_tomoyo_new_test",
- stem: "tomoyo_new_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_new_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_tomoyo_policy_io_test",
- stem: "tomoyo_policy_io_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_policy_io_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_tomoyo_policy_memory_test",
- stem: "tomoyo_policy_memory_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_policy_memory_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
- name: "ltp_tomoyo_rewrite_test",
- stem: "tomoyo_rewrite_test",
- defaults: ["ltp_test_defaults"],
- srcs: ["testcases/kernel/security/tomoyo/tomoyo_rewrite_test.c"],
- local_include_dirs: ["include/old"],
- static_libs: ["libltp_ltp"],
-}
-
-cc_test {
name: "ltp_tpci",
stem: "tpci",
defaults: ["ltp_test_defaults"],
@@ -24977,6 +25086,15 @@ cc_test {
}
cc_test {
+ name: "ltp_tst_fsfreeze",
+ stem: "tst_fsfreeze",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/lib/tst_fsfreeze.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_tst_fuzzy_sync01",
stem: "tst_fuzzy_sync01",
defaults: ["ltp_test_defaults"],
@@ -25058,6 +25176,15 @@ cc_test {
}
cc_test {
+ name: "ltp_tst_lockdown_enabled",
+ stem: "tst_lockdown_enabled",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/lib/tst_lockdown_enabled.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_tst_ncpus",
stem: "tst_ncpus",
defaults: ["ltp_test_defaults"],
@@ -25187,6 +25314,33 @@ cc_test {
}
cc_test {
+ name: "ltp_tst_ns_create",
+ stem: "tst_ns_create",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/lib/tst_ns_create.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_tst_ns_exec",
+ stem: "tst_ns_exec",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/lib/tst_ns_exec.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_tst_ns_ifmove",
+ stem: "tst_ns_ifmove",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/lib/tst_ns_ifmove.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_tst_print_result",
stem: "tst_print_result",
defaults: ["ltp_test_defaults"],
@@ -25279,6 +25433,15 @@ cc_test {
}
cc_test {
+ name: "ltp_tst_secureboot_enabled",
+ stem: "tst_secureboot_enabled",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/lib/tst_secureboot_enabled.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_tst_sleep",
stem: "tst_sleep",
defaults: ["ltp_test_defaults"],
@@ -25625,6 +25788,42 @@ cc_test {
}
cc_test {
+ name: "ltp_utsname01",
+ stem: "utsname01",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/containers/utsname/utsname01.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_utsname02",
+ stem: "utsname02",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/containers/utsname/utsname02.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_utsname03",
+ stem: "utsname03",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/containers/utsname/utsname03.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
+ name: "ltp_utsname04",
+ stem: "utsname04",
+ defaults: ["ltp_test_defaults"],
+ srcs: ["testcases/kernel/containers/utsname/utsname04.c"],
+ local_include_dirs: ["include/old"],
+ static_libs: ["libltp_ltp"],
+}
+
+cc_test {
name: "ltp_variant",
stem: "variant",
defaults: ["ltp_test_defaults"],
diff --git a/include/ipcshm.h b/include/ipcshm.h
deleted file mode 100644
index 08307d4ab..000000000
--- a/include/ipcshm.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * ipcshm.h - common definitions for the IPC shared memory tests
- */
-
-#ifndef __IPCSHM_H
-#define __IPCSHM_H
-
-#include <errno.h>
-#include <sys/wait.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-#include "test.h"
-
-void cleanup(void);
-void setup(void);
-
-#define SHM_RD 0400
-#define SHM_WR 0200
-#define SHM_RW SHM_RD | SHM_WR
-
-#define SHM_SIZE 2048 /* a resonable size for a memory segment */
-#define INT_SIZE 4 /* instead of sizeof(int) */
-
-#define MODE_MASK 0x01FF /* to get the lower nine permission bits */
- /* from shmid_ds.ipc_perm.mode */
-
-key_t shmkey; /* an IPC key generated by ftok() */
-
-void rm_shm(int shm_id);
-
-int getipckey();
-int getuserid(char*);
-
-#endif /* ipcshm.h */
diff --git a/include/lapi/faccessat.h b/include/lapi/faccessat.h
new file mode 100644
index 000000000..05997d975
--- /dev/null
+++ b/include/lapi/faccessat.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+#ifndef FACCESSAT2_H
+#define FACCESSAT2_H
+
+#include "tst_test.h"
+#include "config.h"
+#include "lapi/syscalls.h"
+
+#ifndef HAVE_FACCESSAT2
+int faccessat2(int dirfd, const char *pathname, int mode, int flags)
+{
+ return tst_syscall(__NR_faccessat2, dirfd, pathname, mode, flags);
+}
+#endif
+
+#endif /* FACCESSAT2_H */
diff --git a/include/lapi/fcntl.h b/include/lapi/fcntl.h
index f17220737..cb216e2dc 100644
--- a/include/lapi/fcntl.h
+++ b/include/lapi/fcntl.h
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2014-2023
*/
#ifndef LAPI_FCNTL_H__
@@ -10,9 +11,7 @@
#include <fcntl.h>
#include <sys/socket.h>
-#ifndef O_DIRECT
-# define O_DIRECT 040000
-#endif
+/* NOTE: #define _GNU_SOURCE if you need O_DIRECT in tests */
#ifndef O_CLOEXEC
# define O_CLOEXEC 02000000
@@ -87,20 +86,40 @@
# define AT_FDCWD -100
#endif
+#ifndef AT_SYMLINK_NOFOLLOW
+# define AT_SYMLINK_NOFOLLOW 0x100
+#endif
+
+#ifndef AT_REMOVEDIR
+# define AT_REMOVEDIR 0x200
+#endif
+
#ifndef AT_SYMLINK_FOLLOW
-# define AT_SYMLINK_FOLLOW 0x400
+# define AT_SYMLINK_FOLLOW 0x400
#endif
-#ifndef AT_SYMLINK_NOFOLLOW
-# define AT_SYMLINK_NOFOLLOW 0x100
+#ifndef AT_NO_AUTOMOUNT
+# define AT_NO_AUTOMOUNT 0x800
#endif
#ifndef AT_EMPTY_PATH
-# define AT_EMPTY_PATH 0x1000
+# define AT_EMPTY_PATH 0x1000
#endif
-#ifndef AT_REMOVEDIR
-# define AT_REMOVEDIR 0x200
+#ifndef AT_STATX_SYNC_AS_STAT
+# define AT_STATX_SYNC_AS_STAT 0x0000
+#endif
+
+#ifndef AT_STATX_FORCE_SYNC
+# define AT_STATX_FORCE_SYNC 0x2000
+#endif
+
+#ifndef AT_STATX_DONT_SYNC
+# define AT_STATX_DONT_SYNC 0x4000
+#endif
+
+#ifndef AT_STATX_SYNC_TYPE
+# define AT_STATX_SYNC_TYPE 0x6000
#endif
#ifndef O_NOATIME
diff --git a/include/lapi/fs.h b/include/lapi/fs.h
index 84a168a67..c19ee821d 100644
--- a/include/lapi/fs.h
+++ b/include/lapi/fs.h
@@ -6,6 +6,10 @@
* Email: code@zilogic.com
*/
+#ifndef LAPI_FS_H__
+#define LAPI_FS_H__
+
+#include "config.h"
#ifndef HAVE_MOUNT_SETATTR
# ifdef HAVE_LINUX_FS_H
# include <linux/fs.h>
@@ -16,35 +20,32 @@
#include <limits.h>
#include "lapi/abisize.h"
-#ifndef LAPI_FS_H__
-#define LAPI_FS_H__
-
#ifndef FS_IOC_GETFLAGS
-#define FS_IOC_GETFLAGS _IOR('f', 1, long)
+# define FS_IOC_GETFLAGS _IOR('f', 1, long)
#endif
#ifndef FS_IOC_SETFLAGS
-#define FS_IOC_SETFLAGS _IOW('f', 2, long)
+# define FS_IOC_SETFLAGS _IOW('f', 2, long)
#endif
#ifndef FS_COMPR_FL
-#define FS_COMPR_FL 0x00000004 /* Compress file */
+# define FS_COMPR_FL 0x00000004 /* Compress file */
#endif
#ifndef FS_IMMUTABLE_FL
-#define FS_IMMUTABLE_FL 0x00000010 /* Immutable file */
+# define FS_IMMUTABLE_FL 0x00000010 /* Immutable file */
#endif
#ifndef FS_APPEND_FL
-#define FS_APPEND_FL 0x00000020 /* writes to file may only append */
+# define FS_APPEND_FL 0x00000020 /* writes to file may only append */
#endif
#ifndef FS_NODUMP_FL
-#define FS_NODUMP_FL 0x00000040 /* do not dump file */
+# define FS_NODUMP_FL 0x00000040 /* do not dump file */
#endif
#ifndef FS_VERITY_FL
-#define FS_VERITY_FL 0x00100000 /* Verity protected inode */
+# define FS_VERITY_FL 0x00100000 /* Verity protected inode */
#endif
/*
diff --git a/include/lapi/ioprio.h b/include/lapi/ioprio.h
new file mode 100644
index 000000000..871aa0278
--- /dev/null
+++ b/include/lapi/ioprio.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2019 Linus Walleij <linus.walleij@linaro.org>
+ */
+
+#ifndef LAPI_IOPRIO_H__
+#define LAPI_IOPRIO_H__
+
+#include "config.h"
+
+#ifdef HAVE_LINUX_IOPRIO_H
+# include <linux/ioprio.h>
+#else
+
+enum {
+ IOPRIO_CLASS_NONE = 0,
+ IOPRIO_CLASS_RT,
+ IOPRIO_CLASS_BE,
+ IOPRIO_CLASS_IDLE,
+};
+
+enum {
+ IOPRIO_WHO_PROCESS = 1,
+ IOPRIO_WHO_PGRP,
+ IOPRIO_WHO_USER,
+};
+
+# define IOPRIO_CLASS_SHIFT (13)
+# define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
+
+# define IOPRIO_PRIO_CLASS(data) ((data) >> IOPRIO_CLASS_SHIFT)
+# define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
+
+#endif
+
+/* The RT and BE I/O priority classes have 8 priority levels 0..7 */
+#ifdef IOPRIO_NR_LEVELS
+# define IOPRIO_PRIO_NUM IOPRIO_NR_LEVELS
+#else
+# define IOPRIO_PRIO_NUM 8
+#endif
+
+#ifndef IOPRIO_PRIO_LEVEL
+# define IOPRIO_PRIO_LEVEL(data) ((data) & IOPRIO_PRIO_MASK)
+#endif
+
+#endif /* LAPI_IOPRIO_H__ */
diff --git a/include/lapi/mmap.h b/include/lapi/mmap.h
index 49108338b..7512e9f81 100644
--- a/include/lapi/mmap.h
+++ b/include/lapi/mmap.h
@@ -8,6 +8,11 @@
#define LAPI_MMAP_H__
#include "config.h"
+#include <sys/mman.h>
+
+#ifndef MAP_SHARED_VALIDATE
+# define MAP_SHARED_VALIDATE 0x03
+#endif
#ifndef MAP_HUGETLB
# define MAP_HUGETLB 0x40000
diff --git a/include/lapi/mount.h b/include/lapi/mount.h
index 66e1d1319..c1af944fe 100644
--- a/include/lapi/mount.h
+++ b/include/lapi/mount.h
@@ -33,4 +33,8 @@
# define UMOUNT_NOFOLLOW 8
#endif
+#ifndef MS_NOSYMFOLLOW
+# define MS_NOSYMFOLLOW 256
+#endif
+
#endif /* LAPI_MOUNT_H__ */
diff --git a/include/lapi/sched.h b/include/lapi/sched.h
index 459753020..720b75502 100644
--- a/include/lapi/sched.h
+++ b/include/lapi/sched.h
@@ -13,6 +13,7 @@
#include <inttypes.h>
#include "config.h"
#include "lapi/syscalls.h"
+#include "lapi/sched.h"
struct sched_attr {
uint32_t size;
@@ -54,9 +55,23 @@ struct clone_args {
uint64_t __attribute__((aligned(8))) stack;
uint64_t __attribute__((aligned(8))) stack_size;
uint64_t __attribute__((aligned(8))) tls;
+ uint64_t __attribute__((aligned(8))) set_tid;
+ uint64_t __attribute__((aligned(8))) set_tid_size;
+ uint64_t __attribute__((aligned(8))) cgroup;
};
#endif
+struct clone_args_minimal {
+ uint64_t __attribute__((aligned(8))) flags;
+ uint64_t __attribute__((aligned(8))) pidfd;
+ uint64_t __attribute__((aligned(8))) child_tid;
+ uint64_t __attribute__((aligned(8))) parent_tid;
+ uint64_t __attribute__((aligned(8))) exit_signal;
+ uint64_t __attribute__((aligned(8))) stack;
+ uint64_t __attribute__((aligned(8))) stack_size;
+ uint64_t __attribute__((aligned(8))) tls;
+};
+
#ifndef HAVE_CLONE3
static inline int clone3(struct clone_args *args, size_t size)
{
@@ -135,4 +150,8 @@ static inline int getcpu(unsigned *cpu, unsigned *node)
# define CLONE_NEWTIME 0x00000080
#endif
+#ifndef CLONE_INTO_CGROUP
+# define CLONE_INTO_CGROUP 0x200000000ULL
+#endif
+
#endif /* LAPI_SCHED_H__ */
diff --git a/include/lapi/sem.h b/include/lapi/sem.h
index 3dead200a..e7adac3cf 100644
--- a/include/lapi/sem.h
+++ b/include/lapi/sem.h
@@ -24,4 +24,8 @@ union semun {
# define SEM_STAT_ANY 20
#endif
+#ifndef SEMMSL
+# define SEMMSL 32000
+#endif
+
#endif /* LAPI_SEM_H__ */
diff --git a/include/lapi/stat.h b/include/lapi/stat.h
index ce1f2b678..3606c9eb0 100644
--- a/include/lapi/stat.h
+++ b/include/lapi/stat.h
@@ -10,7 +10,9 @@
#include <stdint.h>
#include <unistd.h>
+#include <sys/stat.h>
#include "lapi/syscalls.h"
+
/*
* Timestamp structure for the timestamps in struct statx.
*
@@ -21,9 +23,7 @@
*
* __reserved is held in case we need a yet finer resolution.
*/
-#if defined(HAVE_STRUCT_STATX_TIMESTAMP)
-#include <sys/stat.h>
-#else
+#ifndef HAVE_STRUCT_STATX_TIMESTAMP
struct statx_timestamp {
int64_t tv_sec;
uint32_t tv_nsec;
@@ -67,9 +67,7 @@ struct statx_timestamp {
* will have values installed for compatibility purposes so that stat() and
* co. can be emulated in userspace.
*/
-#if defined(HAVE_STRUCT_STATX)
-#include <sys/stat.h>
-#else
+#ifndef HAVE_STRUCT_STATX
struct statx {
/* 0x00 */
uint32_t stx_mask;
@@ -102,7 +100,7 @@ struct statx {
};
#endif
-#if !defined(HAVE_STATX)
+#ifndef HAVE_STATX
/*
* statx: wrapper function of statx
@@ -180,8 +178,8 @@ static inline int statx(int dirfd, const char *pathname, unsigned int flags,
# define STATX_MNT_ID 0x00001000U
#endif
-#ifndef STATX_ALL
-# define STATX_ALL 0x00000fffU
+#ifndef STATX_DIOALIGN
+# define STATX_DIOALIGN 0x00002000U
#endif
#ifndef STATX__RESERVED
@@ -223,44 +221,12 @@ static inline int statx(int dirfd, const char *pathname, unsigned int flags,
# define STATX_ATTR_AUTOMOUNT 0x00001000
#endif
-#ifndef STATX_ATTR_VERITY
-# define STATX_ATTR_VERITY 0x00100000
-#endif
-
-#ifndef AT_SYMLINK_NOFOLLOW
-# define AT_SYMLINK_NOFOLLOW 0x100
-#endif
-
-#ifndef AT_REMOVEDIR
-# define AT_REMOVEDIR 0x200
-#endif
-
-#ifndef AT_SYMLINK_FOLLOW
-# define AT_SYMLINK_FOLLOW 0x400
+#ifndef STATX_ATTR_MOUNT_ROOT
+# define STATX_ATTR_MOUNT_ROOT 0x00002000
#endif
-#ifndef AT_NO_AUTOMOUNT
-# define AT_NO_AUTOMOUNT 0x800
-#endif
-
-#ifndef AT_EMPTY_PATH
-# define AT_EMPTY_PATH 0x1000
-#endif
-
-#ifndef AT_STATX_SYNC_TYPE
-# define AT_STATX_SYNC_TYPE 0x6000
-#endif
-
-#ifndef AT_STATX_SYNC_AS_STAT
-# define AT_STATX_SYNC_AS_STAT 0x0000
-#endif
-
-#ifndef AT_STATX_FORCE_SYNC
-# define AT_STATX_FORCE_SYNC 0x2000
-#endif
-
-#ifndef AT_STATX_DONT_SYNC
-# define AT_STATX_DONT_SYNC 0x4000
+#ifndef STATX_ATTR_VERITY
+# define STATX_ATTR_VERITY 0x00100000
#endif
#endif /* LAPI_STAT_H__ */
diff --git a/include/lapi/syscalls/aarch64.in b/include/lapi/syscalls/aarch64.in
index de4ed5fb1..2cb6c2d87 100644
--- a/include/lapi/syscalls/aarch64.in
+++ b/include/lapi/syscalls/aarch64.in
@@ -293,6 +293,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/arc.in b/include/lapi/syscalls/arc.in
index 9f11381db..3e2ee9061 100644
--- a/include/lapi/syscalls/arc.in
+++ b/include/lapi/syscalls/arc.in
@@ -313,6 +313,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/arm.in b/include/lapi/syscalls/arm.in
index 4b0f63a28..7bdbca533 100644
--- a/include/lapi/syscalls/arm.in
+++ b/include/lapi/syscalls/arm.in
@@ -391,6 +391,7 @@ clone3 (__NR_SYSCALL_BASE+435)
close_range (__NR_SYSCALL_BASE+436)
openat2 (__NR_SYSCALL_BASE+437)
pidfd_getfd (__NR_SYSCALL_BASE+438)
+faccessat2 (__NR_SYSCALL_BASE+439)
epoll_pwait2 (__NR_SYSCALL_BASE+441)
quotactl_fd (__NR_SYSCALL_BASE+443)
futex_waitv (__NR_SYSCALL_BASE+449)
diff --git a/include/lapi/syscalls/hppa.in b/include/lapi/syscalls/hppa.in
index b6d32d386..8ebdafafb 100644
--- a/include/lapi/syscalls/hppa.in
+++ b/include/lapi/syscalls/hppa.in
@@ -40,6 +40,7 @@ fsmount 432
fspick 433
pidfd_open 434
close_range 436
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/i386.in b/include/lapi/syscalls/i386.in
index d0e6e9a4b..1472631c4 100644
--- a/include/lapi/syscalls/i386.in
+++ b/include/lapi/syscalls/i386.in
@@ -427,6 +427,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/ia64.in b/include/lapi/syscalls/ia64.in
index 123200624..0ea6e9722 100644
--- a/include/lapi/syscalls/ia64.in
+++ b/include/lapi/syscalls/ia64.in
@@ -340,6 +340,7 @@ pidfd_open 1458
close_range 1460
openat2 1461
pidfd_getfd 1462
+faccessat2 1463
epoll_pwait2 1465
quotactl_fd 1467
futex_waitv 1473
diff --git a/include/lapi/syscalls/loongarch.in b/include/lapi/syscalls/loongarch.in
new file mode 100644
index 000000000..301f611f6
--- /dev/null
+++ b/include/lapi/syscalls/loongarch.in
@@ -0,0 +1,307 @@
+io_setup 0
+io_destroy 1
+io_submit 2
+io_cancel 3
+io_getevents 4
+setxattr 5
+lsetxattr 6
+fsetxattr 7
+getxattr 8
+lgetxattr 9
+fgetxattr 10
+listxattr 11
+llistxattr 12
+flistxattr 13
+removexattr 14
+lremovexattr 15
+fremovexattr 16
+getcwd 17
+lookup_dcookie 18
+eventfd2 19
+epoll_create1 20
+epoll_ctl 21
+epoll_pwait 22
+dup 23
+dup3 24
+fcntl 25
+inotify_init1 26
+inotify_add_watch 27
+inotify_rm_watch 28
+ioctl 29
+ioprio_set 30
+ioprio_get 31
+flock 32
+mknodat 33
+mkdirat 34
+unlinkat 35
+symlinkat 36
+linkat 37
+renameat 38
+umount2 39
+mount 40
+pivot_root 41
+nfsservctl 42
+statfs 43
+fstatfs 44
+truncate 45
+ftruncate 46
+fallocate 47
+faccessat 48
+chdir 49
+fchdir 50
+chroot 51
+fchmod 52
+fchmodat 53
+fchownat 54
+fchown 55
+openat 56
+close 57
+vhangup 58
+pipe2 59
+quotactl 60
+getdents64 61
+lseek 62
+read 63
+write 64
+readv 65
+writev 66
+pread64 67
+pwrite64 68
+preadv 69
+pwritev 70
+sendfile 71
+pselect6 72
+ppoll 73
+signalfd4 74
+vmsplice 75
+splice 76
+tee 77
+readlinkat 78
+fstatat 79
+fstat 80
+sync 81
+fsync 82
+fdatasync 83
+sync_file_range2 84
+sync_file_range 84
+timerfd_create 85
+timerfd_settime 86
+timerfd_gettime 87
+utimensat 88
+acct 89
+capget 90
+capset 91
+personality 92
+exit 93
+exit_group 94
+waitid 95
+set_tid_address 96
+unshare 97
+futex 98
+set_robust_list 99
+get_robust_list 100
+nanosleep 101
+getitimer 102
+setitimer 103
+kexec_load 104
+init_module 105
+delete_module 106
+timer_create 107
+timer_gettime 108
+timer_getoverrun 109
+timer_settime 110
+timer_delete 111
+clock_settime 112
+clock_gettime 113
+clock_getres 114
+clock_nanosleep 115
+syslog 116
+ptrace 117
+sched_setparam 118
+sched_setscheduler 119
+sched_getscheduler 120
+sched_getparam 121
+sched_setaffinity 122
+sched_getaffinity 123
+sched_yield 124
+sched_get_priority_max 125
+sched_get_priority_min 126
+sched_rr_get_interval 127
+restart_syscall 128
+kill 129
+tkill 130
+tgkill 131
+sigaltstack 132
+rt_sigsuspend 133
+rt_sigaction 134
+rt_sigprocmask 135
+rt_sigpending 136
+rt_sigtimedwait 137
+rt_sigqueueinfo 138
+rt_sigreturn 139
+setpriority 140
+getpriority 141
+reboot 142
+setregid 143
+setgid 144
+setreuid 145
+setuid 146
+setresuid 147
+getresuid 148
+setresgid 149
+getresgid 150
+setfsuid 151
+setfsgid 152
+times 153
+setpgid 154
+getpgid 155
+getsid 156
+setsid 157
+getgroups 158
+setgroups 159
+uname 160
+sethostname 161
+setdomainname 162
+getrlimit 163
+setrlimit 164
+getrusage 165
+umask 166
+prctl 167
+getcpu 168
+gettimeofday 169
+settimeofday 170
+adjtimex 171
+getpid 172
+getppid 173
+getuid 174
+geteuid 175
+getgid 176
+getegid 177
+gettid 178
+sysinfo 179
+mq_open 180
+mq_unlink 181
+mq_timedsend 182
+mq_timedreceive 183
+mq_notify 184
+mq_getsetattr 185
+msgget 186
+msgctl 187
+msgrcv 188
+msgsnd 189
+semget 190
+semctl 191
+semtimedop 192
+semop 193
+shmget 194
+shmctl 195
+shmat 196
+shmdt 197
+socket 198
+socketpair 199
+bind 200
+listen 201
+accept 202
+connect 203
+getsockname 204
+getpeername 205
+sendto 206
+recvfrom 207
+setsockopt 208
+getsockopt 209
+shutdown 210
+sendmsg 211
+recvmsg 212
+readahead 213
+brk 214
+munmap 215
+mremap 216
+add_key 217
+request_key 218
+keyctl 219
+clone 220
+execve 221
+mmap 222
+fadvise64 223
+swapon 224
+swapoff 225
+mprotect 226
+msync 227
+mlock 228
+munlock 229
+mlockall 230
+munlockall 231
+mincore 232
+madvise 233
+remap_file_pages 234
+mbind 235
+get_mempolicy 236
+set_mempolicy 237
+migrate_pages 238
+move_pages 239
+rt_tgsigqueueinfo 240
+perf_event_open 241
+accept4 242
+recvmmsg 243
+wait4 260
+prlimit64 261
+fanotify_init 262
+fanotify_mark 263
+name_to_handle_at 264
+open_by_handle_at 265
+clock_adjtime 266
+syncfs 267
+setns 268
+sendmmsg 269
+process_vm_readv 270
+process_vm_writev 271
+kcmp 272
+finit_module 273
+sched_setattr 274
+sched_getattr 275
+renameat2 276
+seccomp 277
+getrandom 278
+memfd_create 279
+bpf 280
+execveat 281
+userfaultfd 282
+membarrier 283
+mlock2 284
+copy_file_range 285
+preadv2 286
+pwritev2 287
+pkey_mprotect 288
+pkey_alloc 289
+pkey_free 290
+statx 291
+io_pgetevents 292
+rseq 293
+kexec_file_load 294
+pidfd_send_signal 424
+io_uring_setup 425
+io_uring_enter 426
+io_uring_register 427
+open_tree 428
+move_mount 429
+fsopen 430
+fsconfig 431
+fsmount 432
+fspick 433
+pidfd_open 434
+clone3 435
+close_range 436
+openat2 437
+pidfd_getfd 438
+faccessat2 439
+process_madvise 440
+epoll_pwait2 441
+mount_setattr 442
+quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
+memfd_secret 447
+process_mrelease 448
+futex_waitv 449
+set_mempolicy_home_node 450
diff --git a/include/lapi/syscalls/order b/include/lapi/syscalls/order
index 548097681..c18aa38cf 100644
--- a/include/lapi/syscalls/order
+++ b/include/lapi/syscalls/order
@@ -4,6 +4,7 @@ arm
hppa
i386
ia64
+loongarch
mips_n32
mips_n64
mips_o32
diff --git a/include/lapi/syscalls/powerpc.in b/include/lapi/syscalls/powerpc.in
index d5de621e1..545d9d3d6 100644
--- a/include/lapi/syscalls/powerpc.in
+++ b/include/lapi/syscalls/powerpc.in
@@ -420,6 +420,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/powerpc64.in b/include/lapi/syscalls/powerpc64.in
index d5de621e1..545d9d3d6 100644
--- a/include/lapi/syscalls/powerpc64.in
+++ b/include/lapi/syscalls/powerpc64.in
@@ -420,6 +420,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/s390.in b/include/lapi/syscalls/s390.in
index 6505f3822..7213ac5f8 100644
--- a/include/lapi/syscalls/s390.in
+++ b/include/lapi/syscalls/s390.in
@@ -407,6 +407,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/s390x.in b/include/lapi/syscalls/s390x.in
index bc5d2b34c..879012e2b 100644
--- a/include/lapi/syscalls/s390x.in
+++ b/include/lapi/syscalls/s390x.in
@@ -355,6 +355,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/sh.in b/include/lapi/syscalls/sh.in
index 316ffe5f1..7d5192a27 100644
--- a/include/lapi/syscalls/sh.in
+++ b/include/lapi/syscalls/sh.in
@@ -401,6 +401,7 @@ pidfd_open 434
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/sparc.in b/include/lapi/syscalls/sparc.in
index e0c60a360..91d2fb1c2 100644
--- a/include/lapi/syscalls/sparc.in
+++ b/include/lapi/syscalls/sparc.in
@@ -406,6 +406,7 @@ pidfd_open 434
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/sparc64.in b/include/lapi/syscalls/sparc64.in
index 0acde6856..1f2fc59b7 100644
--- a/include/lapi/syscalls/sparc64.in
+++ b/include/lapi/syscalls/sparc64.in
@@ -371,6 +371,7 @@ pidfd_open 434
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in
index 1863e1df7..dc61aa56e 100644
--- a/include/lapi/syscalls/x86_64.in
+++ b/include/lapi/syscalls/x86_64.in
@@ -348,6 +348,7 @@ clone3 435
close_range 436
openat2 437
pidfd_getfd 438
+faccessat2 439
epoll_pwait2 441
quotactl_fd 443
futex_waitv 449
diff --git a/include/libnewipc.h b/include/libnewipc.h
index 1e126ca1c..969c93292 100644
--- a/include/libnewipc.h
+++ b/include/libnewipc.h
@@ -53,6 +53,8 @@ int get_used_sysvipc(const char *file, const int lineno, const char *sysvipc_fil
get_used_sysvipc(__FILE__, __LINE__, "/proc/sysvipc/msg")
#define GET_USED_SEGMENTS() \
get_used_sysvipc(__FILE__, __LINE__, "/proc/sysvipc/shm")
+#define GET_USED_ARRAYS() \
+ get_used_sysvipc(__FILE__, __LINE__, "/proc/sysvipc/sem")
void *probe_free_addr(const char *file, const int lineno);
#define PROBE_FREE_ADDR() \
diff --git a/include/mk/automake.mk b/include/mk/automake.mk
index ee3b7f1b8..3ecdd3144 100644
--- a/include/mk/automake.mk
+++ b/include/mk/automake.mk
@@ -99,8 +99,7 @@ AUTOGENERATED_FILES = \
include/mk/config.mk \
include/mk/features.mk \
lib/ltp.pc \
- m4/Makefile \
- execltp
+ m4/Makefile
distclean:: %: clean ac-distclean
for d in $(AUTOCONFED_SUBDIRS); do \
diff --git a/include/safe_net_fn.h b/include/safe_net_fn.h
index ff81b1337..6c63cb2cf 100644
--- a/include/safe_net_fn.h
+++ b/include/safe_net_fn.h
@@ -73,6 +73,9 @@ int safe_getsockname(const char *file, const int lineno,
int safe_gethostname(const char *file, const int lineno,
char *name, size_t size);
+int safe_sethostname(const char *file, const int lineno,
+ const char *name, size_t size);
+
int tst_getsockport(const char *file, const int lineno, int sockfd);
unsigned short tst_get_unused_port(const char *file, const int lineno,
diff --git a/include/tst_buffers.h b/include/tst_buffers.h
index d19ac8cf0..b5f355f0f 100644
--- a/include/tst_buffers.h
+++ b/include/tst_buffers.h
@@ -25,6 +25,11 @@ struct tst_buffers {
* Array of iov buffer sizes terminated by -1.
*/
int *iov_sizes;
+ /*
+ * If size and iov_sizes is NULL this is the string we want to strdup()
+ * into the buffer.
+ */
+ char *str;
};
/*
@@ -47,6 +52,12 @@ char *tst_strdup(const char *str);
void *tst_alloc(size_t size);
/*
+ * Printf into a guarded buffer.
+ */
+char *tst_aprintf(const char *fmt, ...)
+ __attribute__((format (printf, 1, 2)));
+
+/*
* Allocates iovec structure including the buffers.
*
* @sizes -1 terminated array of buffer sizes.
diff --git a/include/tst_cgroup.h b/include/tst_cgroup.h
index 2826ddad1..be14d07c6 100644
--- a/include/tst_cgroup.h
+++ b/include/tst_cgroup.h
@@ -157,6 +157,10 @@ const char *
tst_cg_group_name(const struct tst_cg_group *const cg)
__attribute__ ((nonnull, warn_unused_result));
+/* This call returns a fd pointing to a v2 directory */
+int tst_cg_group_unified_dir_fd(const struct tst_cg_group *const cg)
+ __attribute__ ((nonnull, warn_unused_result));
+
/* Remove a descendant CGroup */
struct tst_cg_group *
tst_cg_group_rm(struct tst_cg_group *const cg)
diff --git a/include/tst_clone.h b/include/tst_clone.h
index 9ffdc68d1..7b278dfa7 100644
--- a/include/tst_clone.h
+++ b/include/tst_clone.h
@@ -11,6 +11,7 @@
struct tst_clone_args {
uint64_t flags;
uint64_t exit_signal;
+ uint64_t cgroup;
};
/* clone3 with fallbacks to clone when possible. Be aware that it
diff --git a/include/tst_kernel.h b/include/tst_kernel.h
index 9e17bb71e..9d3a8d315 100644
--- a/include/tst_kernel.h
+++ b/include/tst_kernel.h
@@ -10,8 +10,18 @@
*/
int tst_kernel_bits(void);
-/**
- * Checks support for the kernel driver.
+/*
+ * Checks if the kernel module is built-in.
+ *
+ * @param driver The name of the driver.
+ * @return Returns 0 if builtin driver
+ * -1 when driver is missing or config file not available.
+ * On Android *always* 0 (always expect the driver is available).
+ */
+int tst_check_builtin_driver(const char *driver);
+
+/*
+ * Checks support for the kernel module (both built-in and loadable).
*
* @param driver The name of the driver.
* @return Returns 0 if the kernel has the driver,
diff --git a/include/tst_memutils.h b/include/tst_memutils.h
index 45dec55bc..19b593430 100644
--- a/include/tst_memutils.h
+++ b/include/tst_memutils.h
@@ -26,6 +26,11 @@ void tst_pollute_memory(size_t maxsize, int fillchar);
long long tst_available_mem(void);
/*
+ * Read the value of SwapFree from /proc/meminfo.
+ */
+long long tst_available_swap(void);
+
+/*
* Enable OOM protection to prevent process($PID) being killed by OOM Killer.
* echo -1000 >/proc/$PID/oom_score_adj
*
diff --git a/include/tst_minmax.h b/include/tst_minmax.h
index 9d7d596fc..1597fbc97 100644
--- a/include/tst_minmax.h
+++ b/include/tst_minmax.h
@@ -1,10 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2020-2023
*/
#ifndef TST_MINMAX_H__
#define TST_MINMAX_H__
+#include <sys/param.h>
+
#ifndef MIN
# define MIN(a, b) ({ \
typeof(a) _a = (a); \
diff --git a/include/tst_netdevice.h b/include/tst_netdevice.h
index f02661208..5e62ba065 100644
--- a/include/tst_netdevice.h
+++ b/include/tst_netdevice.h
@@ -5,6 +5,8 @@
#ifndef TST_NETDEVICE_H
#define TST_NETDEVICE_H
+#include "tst_rtnetlink.h"
+
/* Find device index for given network interface name. */
int tst_netdev_index_by_name(const char *file, const int lineno,
const char *ifname);
@@ -18,69 +20,70 @@ int tst_netdev_set_state(const char *file, const int lineno,
tst_netdev_set_state(__FILE__, __LINE__, (ifname), (up))
/* Create a connected pair of virtual network devices */
-int tst_create_veth_pair(const char *file, const int lineno,
+int tst_create_veth_pair(const char *file, const int lineno, int strict,
const char *ifname1, const char *ifname2);
#define CREATE_VETH_PAIR(ifname1, ifname2) \
- tst_create_veth_pair(__FILE__, __LINE__, (ifname1), (ifname2))
+ tst_create_veth_pair(__FILE__, __LINE__, 1, (ifname1), (ifname2))
-int tst_netdev_add_device(const char *file, const int lineno,
+int tst_netdev_add_device(const char *file, const int lineno, int strict,
const char *ifname, const char *devtype);
#define NETDEV_ADD_DEVICE(ifname, devtype) \
- tst_netdev_add_device(__FILE__, __LINE__, (ifname), (devtype))
+ tst_netdev_add_device(__FILE__, __LINE__, 1, (ifname), (devtype))
-int tst_netdev_remove_device(const char *file, const int lineno,
+int tst_netdev_remove_device(const char *file, const int lineno, int strict,
const char *ifname);
#define NETDEV_REMOVE_DEVICE(ifname) \
- tst_netdev_remove_device(__FILE__, __LINE__, (ifname))
+ tst_netdev_remove_device(__FILE__, __LINE__, 1, (ifname))
-int tst_netdev_add_address(const char *file, const int lineno,
+int tst_netdev_add_address(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *address,
unsigned int prefix, size_t addrlen, unsigned int flags);
#define NETDEV_ADD_ADDRESS(ifname, family, address, prefix, addrlen, flags) \
- tst_netdev_add_address(__FILE__, __LINE__, (ifname), (family), \
+ tst_netdev_add_address(__FILE__, __LINE__, 1, (ifname), (family), \
(address), (prefix), (addrlen), (flags))
-int tst_netdev_add_address_inet(const char *file, const int lineno,
+int tst_netdev_add_address_inet(const char *file, const int lineno, int strict,
const char *ifname, in_addr_t address, unsigned int prefix,
unsigned int flags);
#define NETDEV_ADD_ADDRESS_INET(ifname, address, prefix, flags) \
- tst_netdev_add_address_inet(__FILE__, __LINE__, (ifname), (address), \
- (prefix), (flags))
+ tst_netdev_add_address_inet(__FILE__, __LINE__, 1, (ifname), \
+ (address), (prefix), (flags))
-int tst_netdev_remove_address(const char *file, const int lineno,
+int tst_netdev_remove_address(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *address,
size_t addrlen);
#define NETDEV_REMOVE_ADDRESS(ifname, family, address, addrlen) \
- tst_netdev_remove_address(__FILE__, __LINE__, (ifname), (family), \
+ tst_netdev_remove_address(__FILE__, __LINE__, 1, (ifname), (family), \
(address), (addrlen))
int tst_netdev_remove_address_inet(const char *file, const int lineno,
- const char *ifname, in_addr_t address);
+ int strict, const char *ifname, in_addr_t address);
#define NETDEV_REMOVE_ADDRESS_INET(ifname, address) \
- tst_netdev_remove_address_inet(__FILE__, __LINE__, (ifname), (address))
+ tst_netdev_remove_address_inet(__FILE__, __LINE__, 1, (ifname), \
+ (address))
-int tst_netdev_change_ns_fd(const char *file, const int lineno,
+int tst_netdev_change_ns_fd(const char *file, const int lineno, int strict,
const char *ifname, int nsfd);
#define NETDEV_CHANGE_NS_FD(ifname, nsfd) \
- tst_netdev_change_ns_fd(__FILE__, __LINE__, (ifname), (nsfd))
+ tst_netdev_change_ns_fd(__FILE__, __LINE__, 1, (ifname), (nsfd))
-int tst_netdev_change_ns_pid(const char *file, const int lineno,
+int tst_netdev_change_ns_pid(const char *file, const int lineno, int strict,
const char *ifname, pid_t nspid);
#define NETDEV_CHANGE_NS_PID(ifname, nspid) \
- tst_netdev_change_ns_pid(__FILE__, __LINE__, (ifname), (nspid))
+ tst_netdev_change_ns_pid(__FILE__, __LINE__, 1, (ifname), (nspid))
/*
* Add new static entry to main routing table. If you specify gateway address,
* the interface name is optional.
*/
-int tst_netdev_add_route(const char *file, const int lineno,
+int tst_netdev_add_route(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *srcaddr,
unsigned int srcprefix, size_t srclen, const void *dstaddr,
unsigned int dstprefix, size_t dstlen, const void *gateway,
size_t gatewaylen);
#define NETDEV_ADD_ROUTE(ifname, family, srcaddr, srcprefix, srclen, dstaddr, \
dstprefix, dstlen, gateway, gatewaylen) \
- tst_netdev_add_route(__FILE__, __LINE__, (ifname), (family), \
+ tst_netdev_add_route(__FILE__, __LINE__, 1, (ifname), (family), \
(srcaddr), (srcprefix), (srclen), (dstaddr), (dstprefix), \
(dstlen), (gateway), (gatewaylen))
@@ -89,25 +92,25 @@ int tst_netdev_add_route(const char *file, const int lineno,
* or dstprefix to 0, the corresponding address will be ignored. Interface
* name is optional if gateway address is non-zero.
*/
-int tst_netdev_add_route_inet(const char *file, const int lineno,
+int tst_netdev_add_route_inet(const char *file, const int lineno, int strict,
const char *ifname, in_addr_t srcaddr, unsigned int srcprefix,
in_addr_t dstaddr, unsigned int dstprefix, in_addr_t gateway);
#define NETDEV_ADD_ROUTE_INET(ifname, srcaddr, srcprefix, dstaddr, dstprefix, \
gateway) \
- tst_netdev_add_route_inet(__FILE__, __LINE__, (ifname), (srcaddr), \
+ tst_netdev_add_route_inet(__FILE__, __LINE__, 1, (ifname), (srcaddr), \
(srcprefix), (dstaddr), (dstprefix), (gateway))
/*
* Remove static entry from main routing table.
*/
-int tst_netdev_remove_route(const char *file, const int lineno,
+int tst_netdev_remove_route(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *srcaddr,
unsigned int srcprefix, size_t srclen, const void *dstaddr,
unsigned int dstprefix, size_t dstlen, const void *gateway,
size_t gatewaylen);
#define NETDEV_REMOVE_ROUTE(ifname, family, srcaddr, srcprefix, srclen, \
dstaddr, dstprefix, dstlen, gateway, gatewaylen) \
- tst_netdev_remove_route(__FILE__, __LINE__, (ifname), (family), \
+ tst_netdev_remove_route(__FILE__, __LINE__, 1, (ifname), (family), \
(srcaddr), (srcprefix), (srclen), (dstaddr), (dstprefix), \
(dstlen), (gateway), (gatewaylen))
@@ -115,11 +118,74 @@ int tst_netdev_remove_route(const char *file, const int lineno,
* Simplified function for removing IPv4 static route.
*/
int tst_netdev_remove_route_inet(const char *file, const int lineno,
- const char *ifname, in_addr_t srcaddr, unsigned int srcprefix,
- in_addr_t dstaddr, unsigned int dstprefix, in_addr_t gateway);
+ int strict, const char *ifname, in_addr_t srcaddr,
+ unsigned int srcprefix, in_addr_t dstaddr, unsigned int dstprefix,
+ in_addr_t gateway);
#define NETDEV_REMOVE_ROUTE_INET(ifname, srcaddr, srcprefix, dstaddr, \
dstprefix, gateway) \
- tst_netdev_remove_route_inet(__FILE__, __LINE__, (ifname), (srcaddr), \
- (srcprefix), (dstaddr), (dstprefix), (gateway))
+ tst_netdev_remove_route_inet(__FILE__, __LINE__, 1, (ifname), \
+ (srcaddr), (srcprefix), (dstaddr), (dstprefix), (gateway))
+
+/*
+ * Add queueing discipline. Network interface name is optional.
+ */
+int tst_netdev_add_qdisc(const char *file, const int lineno, int strict,
+ const char *ifname, unsigned int family, unsigned int parent,
+ unsigned int handle, const char *qd_kind,
+ const struct tst_rtnl_attr_list *config);
+#define NETDEV_ADD_QDISC(ifname, family, parent, handle, qd_kind, config) \
+ tst_netdev_add_qdisc(__FILE__, __LINE__, 1, (ifname), (family), \
+ (parent), (handle), (qd_kind), (config))
+
+/*
+ * Remove queueing discipline.
+ */
+int tst_netdev_remove_qdisc(const char *file, const int lineno, int strict,
+ const char *ifname, unsigned int family, unsigned int parent,
+ unsigned int handle, const char *qd_kind);
+#define NETDEV_REMOVE_QDISC(ifname, family, parent, handle, qd_kind) \
+ tst_netdev_remove_qdisc(__FILE__, __LINE__, 1, (ifname), (family), \
+ (parent), (handle), (qd_kind))
+
+/*
+ * Add traffic class to queueing discipline. Network interface name is
+ * optional.
+ */
+int tst_netdev_add_traffic_class(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, const char *qd_kind,
+ const struct tst_rtnl_attr_list *config);
+#define NETDEV_ADD_TRAFFIC_CLASS(ifname, parent, handle, qd_kind, config) \
+ tst_netdev_add_traffic_class(__FILE__, __LINE__, 1, (ifname), \
+ (parent), (handle), (qd_kind), (config))
+
+int tst_netdev_remove_traffic_class(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, const char *qd_kind);
+#define NETDEV_REMOVE_TRAFFIC_CLASS(ifname, parent, handle, qd_kind) \
+ tst_netdev_remove_traffic_class(__FILE__, __LINE__, 1, (ifname), \
+ (parent), (handle), (qd_kind))
+
+/*
+ * Add traffic filter to queueing discipline. Protocol should be en ETH_P_*
+ * constant in host byte order. Network interface name is optional.
+ */
+int tst_netdev_add_traffic_filter(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, unsigned int protocol, unsigned int priority,
+ const char *f_kind, const struct tst_rtnl_attr_list *config);
+#define NETDEV_ADD_TRAFFIC_FILTER(ifname, parent, handle, protocol, priority, \
+ f_kind, config) \
+ tst_netdev_add_traffic_filter(__FILE__, __LINE__, 1, (ifname), \
+ (parent), (handle), (protocol), (priority), (f_kind), (config))
+
+int tst_netdev_remove_traffic_filter(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, unsigned int protocol, unsigned int priority,
+ const char *f_kind);
+#define NETDEV_REMOVE_TRAFFIC_FILTER(ifname, parent, handle, protocol, \
+ priority, f_kind) \
+ tst_netdev_remove_traffic_filter(__FILE__, __LINE__, 1, (ifname), \
+ (parent), (handle), (protocol), (priority), (f_kind))
#endif /* TST_NETDEVICE_H */
diff --git a/include/tst_pid.h b/include/tst_pid.h
index 8d999a655..774c845ce 100644
--- a/include/tst_pid.h
+++ b/include/tst_pid.h
@@ -42,4 +42,12 @@ static inline int tst_get_free_pids(void (*cleanup_fn)(void))
}
#endif
+/*
+ * Direct getpid() syscall. Some glibc versions cache getpid() return value
+ * which can cause confusing issues for example in processes created by
+ * direct clone() syscall (without using the glibc wrapper). Use this function
+ * whenever the current process may be a child of the main test process.
+ */
+pid_t tst_getpid(void);
+
#endif /* TST_PID_H__ */
diff --git a/include/tst_safe_net.h b/include/tst_safe_net.h
index e85b79a3e..98f0256fd 100644
--- a/include/tst_safe_net.h
+++ b/include/tst_safe_net.h
@@ -68,6 +68,9 @@
#define SAFE_GETHOSTNAME(name, size) \
safe_gethostname(__FILE__, __LINE__, name, size)
+#define SAFE_SETHOSTNAME(name, size) \
+ safe_sethostname(__FILE__, __LINE__, name, size)
+
#define TST_GETSOCKPORT(sockfd) \
tst_getsockport(__FILE__, __LINE__, sockfd)
diff --git a/include/tst_safe_posix_ipc.h b/include/tst_safe_posix_ipc.h
index 2d3d0928f..e7892f2af 100644
--- a/include/tst_safe_posix_ipc.h
+++ b/include/tst_safe_posix_ipc.h
@@ -121,7 +121,7 @@ static inline int safe_mq_send(const char *file, const int lineno,
if (rval == -1) {
tst_brk_(file, lineno, TBROK | TERRNO,
- "mq_send(%d,%s,%lu,%d) failed", mqdes, msg_ptr,
+ "mq_send(%d,%s,%zu,%d) failed", mqdes, msg_ptr,
msg_len, msg_prio);
}
diff --git a/include/tst_safe_pthread.h b/include/tst_safe_pthread.h
index 8fb553929..360b561b6 100644
--- a/include/tst_safe_pthread.h
+++ b/include/tst_safe_pthread.h
@@ -52,4 +52,56 @@ int safe_pthread_cancel(const char *file, const int lineno,
#define SAFE_PTHREAD_CANCEL(thread_id) \
safe_pthread_cancel(__FILE__, __LINE__, thread_id);
+int safe_pthread_mutexattr_init(const char *file, const int lineno,
+ pthread_mutexattr_t *attr);
+#define SAFE_PTHREAD_MUTEXATTR_INIT(attr) \
+ safe_pthread_mutexattr_init(__FILE__, __LINE__, (attr))
+
+int safe_pthread_mutexattr_destroy(const char *file, const int lineno,
+ pthread_mutexattr_t *attr);
+#define SAFE_PTHREAD_MUTEXATTR_DESTROY(attr) \
+ safe_pthread_mutexattr_destroy(__FILE__, __LINE__, (attr))
+
+int safe_pthread_mutexattr_settype(const char *file, const int lineno,
+ pthread_mutexattr_t *attr, int type);
+#define SAFE_PTHREAD_MUTEXATTR_SETTYPE(attr, type) \
+ safe_pthread_mutexattr_settype(__FILE__, __LINE__, (attr), (type))
+
+int safe_pthread_mutex_init(const char *file, const int lineno,
+ pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
+#define SAFE_PTHREAD_MUTEX_INIT(mutex, attr) \
+ safe_pthread_mutex_init(__FILE__, __LINE__, (mutex), (attr))
+
+int safe_pthread_mutex_destroy(const char *file, const int lineno,
+ pthread_mutex_t *mutex);
+#define SAFE_PTHREAD_MUTEX_DESTROY(mutex) \
+ safe_pthread_mutex_destroy(__FILE__, __LINE__, (mutex))
+
+int safe_pthread_mutex_lock(const char *file, const int lineno,
+ pthread_mutex_t *mutex);
+#define SAFE_PTHREAD_MUTEX_LOCK(mutex) \
+ safe_pthread_mutex_lock(__FILE__, __LINE__, (mutex))
+
+/* Terminates the test on any error other than EBUSY */
+int safe_pthread_mutex_trylock(const char *file, const int lineno,
+ pthread_mutex_t *mutex);
+#define SAFE_PTHREAD_MUTEX_TRYLOCK(mutex) \
+ safe_pthread_mutex_trylock(__FILE__, __LINE__, (mutex))
+
+/* Terminates the test on any error other than ETIMEDOUT */
+int safe_pthread_mutex_timedlock(const char *file, const int lineno,
+ pthread_mutex_t *mutex, const struct timespec *abstime);
+#define SAFE_PTHREAD_MUTEX_TIMEDLOCK(mutex, abstime) \
+ safe_pthread_mutex_timedlock(__FILE__, __LINE__, (mutex), (abstime))
+
+int safe_pthread_mutex_unlock(const char *file, const int lineno,
+ pthread_mutex_t *mutex);
+#define SAFE_PTHREAD_MUTEX_UNLOCK(mutex) \
+ safe_pthread_mutex_unlock(__FILE__, __LINE__, (mutex))
+
+int safe_pthread_kill(const char *file, const int lineno,
+ pthread_t thread, int sig);
+#define SAFE_PTHREAD_KILL(thread, sig) \
+ safe_pthread_kill(__FILE__, __LINE__, (thread), (sig))
+
#endif /* TST_SAFE_PTHREAD_H__ */
diff --git a/include/tst_test.h b/include/tst_test.h
index 22acfba59..75c2109b9 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -177,6 +177,7 @@ struct tst_test {
int child_needs_reinit:1;
int needs_devfs:1;
int restore_wallclock:1;
+
/*
* If set the test function will be executed for all available
* filesystems and the current filesystem type would be set in the
@@ -186,8 +187,11 @@ struct tst_test {
* to the test function.
*/
int all_filesystems:1;
+
int skip_in_lockdown:1;
+ int skip_in_secureboot:1;
int skip_in_compat:1;
+
/*
* If set, the hugetlbfs will be mounted at .mntpoint.
*/
@@ -206,6 +210,9 @@ struct tst_test {
/* Minimum size(MB) of MemAvailable required by the test */
unsigned long min_mem_avail;
+ /* Minimum size(MB) of SwapFree required by the test */
+ unsigned long min_swap_avail;
+
/*
* Two policies for reserving hugepage:
*
diff --git a/include/tst_test_macros.h b/include/tst_test_macros.h
index 231c04951..bd0c491c1 100644
--- a/include/tst_test_macros.h
+++ b/include/tst_test_macros.h
@@ -51,7 +51,7 @@ extern void *TST_RET_PTR;
tst_res_(__FILE__, __LINE__, RES, \
TST_FMT_(TST_2_(dummy, ##__VA_ARGS__, SCALL) FMT, __VA_ARGS__), PAR, PAR2)
-#define TST_EXP_POSITIVE_(SCALL, SSCALL, ...) \
+#define TST_EXP_POSITIVE__(SCALL, SSCALL, ...) \
do { \
TEST(SCALL); \
\
@@ -73,46 +73,59 @@ extern void *TST_RET_PTR;
\
} while (0)
+#define TST_EXP_POSITIVE_(SCALL, ...) \
+ ({ \
+ TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__); \
+ TST_RET; \
+ })
+
#define TST_EXP_POSITIVE(SCALL, ...) \
- do { \
- TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__); \
+ ({ \
+ TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__); \
\
if (TST_PASS) { \
TST_MSGP_(TPASS, " returned %ld", \
TST_RET, #SCALL, ##__VA_ARGS__); \
} \
- } while (0)
+ \
+ TST_RET; \
+ })
#define TST_EXP_FD_SILENT(SCALL, ...) TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__)
#define TST_EXP_FD(SCALL, ...) \
- do { \
- TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__); \
+ ({ \
+ TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__); \
\
if (TST_PASS) \
TST_MSGP_(TPASS, " returned fd %ld", TST_RET, \
#SCALL, ##__VA_ARGS__); \
- } while (0)
+ \
+ TST_RET; \
+ })
-#define TST_EXP_FD_OR_FAIL(SCALL, ERRNO, ...) \
- do { \
+#define TST_EXP_FD_OR_FAIL(SCALL, ERRNO, ...) \
+ ({ \
if (ERRNO) \
TST_EXP_FAIL(SCALL, ERRNO, ##__VA_ARGS__); \
else \
TST_EXP_FD(SCALL, ##__VA_ARGS__); \
\
- } while (0)
+ TST_RET; \
+ })
#define TST_EXP_PID_SILENT(SCALL, ...) TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__)
#define TST_EXP_PID(SCALL, ...) \
- do { \
- TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__); \
+ ({ \
+ TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__); \
\
if (TST_PASS) \
TST_MSGP_(TPASS, " returned pid %ld", TST_RET, \
#SCALL, ##__VA_ARGS__); \
- } while (0)
+ \
+ TST_RET; \
+ })
#define TST_EXP_VAL_SILENT_(SCALL, VAL, SSCALL, ...) \
do { \
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644
index 000000000..eb9901169
--- /dev/null
+++ b/lib/.gitignore
@@ -0,0 +1,3 @@
+/ltp-version.h
+/cached-version
+/ltp.pc
diff --git a/lib/Makefile b/lib/Makefile
index 9b9906f25..67169f149 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,6 +20,19 @@ pc_file := $(DESTDIR)/$(datarootdir)/pkgconfig/ltp.pc
INSTALL_TARGETS := $(pc_file)
+tst_test.o: ltp-version.h
+
+ltp-version.h: gen_version
+
+MAKE_TARGETS += gen_version
+
+.PHONY: gen_version
+gen_version:
+ @echo GEN ltp-version.h
+ @$(top_srcdir)/lib/gen_version.sh
+
+CLEAN_TARGETS += ltp-version.h cached-version
+
$(pc_file):
test -d "$(@D)" || mkdir -p "$(@D)"
install -m $(INSTALL_MODE) "$(builddir)/$(@F)" "$@"
diff --git a/lib/gen_version.sh b/lib/gen_version.sh
new file mode 100755
index 000000000..5d4250755
--- /dev/null
+++ b/lib/gen_version.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+touch cached-version
+
+if git describe >/dev/null 2>&1; then
+ VERSION=`git describe`
+else
+ VERSION=`cat $(dirname $0)/../VERSION`
+fi
+
+CACHED_VERSION=`cat cached-version`
+
+if [ "$CACHED_VERSION" != "$VERSION" ]; then
+ echo "$VERSION" > cached-version
+ echo "#define LTP_VERSION \"$VERSION\"" > ltp-version.h
+fi
diff --git a/lib/newlib_tests/Makefile b/lib/newlib_tests/Makefile
index 1fbf7649a..a915a7f12 100644
--- a/lib/newlib_tests/Makefile
+++ b/lib/newlib_tests/Makefile
@@ -7,7 +7,7 @@ CFLAGS += -W -Wall
LDLIBS += -lltp
test08 test09 test15 tst_fuzzy_sync01 tst_fuzzy_sync02 tst_fuzzy_sync03: CFLAGS += -pthread
-tst_expiration_timer tst_fuzzy_sync03: LDLIBS += -lrt
+tst_expiration_timer tst_fuzzy_sync01 tst_fuzzy_sync02 tst_fuzzy_sync03: LDLIBS += -lrt
ifeq ($(ANDROID),1)
FILTER_OUT_MAKE_TARGETS += test08
diff --git a/lib/random_range.c b/lib/random_range.c
index 510a4a1ff..4c96fd913 100644
--- a/lib/random_range.c
+++ b/lib/random_range.c
@@ -80,7 +80,7 @@ struct range {
* into an integer, or >= 0 if it was successfully
* parsed. The resulting integer will be stored in
* *val. If parse_func is NULL, parse_ranges will parse
- * the tokens in a manner consistent with the the sscanf
+ * the tokens in a manner consistent with the sscanf
* %i format.
* range_ptr A user-supplied char **, which will be set to point
* at malloc'd space which holds the parsed range
diff --git a/lib/safe_file_ops.c b/lib/safe_file_ops.c
index f803691d8..63ae2dbbe 100644
--- a/lib/safe_file_ops.c
+++ b/lib/safe_file_ops.c
@@ -76,7 +76,7 @@ int file_scanf(const char *file, const int lineno,
f = fopen(path, "r");
if (f == NULL) {
- tst_resm_(file, lineno, TWARN, "Failed to open FILE '%s'",
+ tst_resm_(file, lineno, TINFO, "Failed to open FILE '%s'",
path);
return 1;
}
@@ -88,20 +88,20 @@ int file_scanf(const char *file, const int lineno,
va_end(va);
if (ret == EOF) {
- tst_resm_(file, lineno, TWARN,
+ tst_resm_(file, lineno, TINFO,
"The FILE '%s' ended prematurely", path);
goto err;
}
if (ret != exp_convs) {
- tst_resm_(file, lineno, TWARN,
+ tst_resm_(file, lineno, TINFO,
"Expected %i conversions got %i FILE '%s'",
exp_convs, ret, path);
goto err;
}
if (fclose(f)) {
- tst_resm_(file, lineno, TWARN, "Failed to close FILE '%s'",
+ tst_resm_(file, lineno, TINFO, "Failed to close FILE '%s'",
path);
return 1;
}
@@ -110,7 +110,7 @@ int file_scanf(const char *file, const int lineno,
err:
if (fclose(f)) {
- tst_resm_(file, lineno, TWARN, "Failed to close FILE '%s'",
+ tst_resm_(file, lineno, TINFO, "Failed to close FILE '%s'",
path);
}
@@ -218,7 +218,7 @@ int file_printf(const char *file, const int lineno,
f = fopen(path, "w");
if (f == NULL) {
- tst_resm_(file, lineno, TWARN, "Failed to open FILE '%s'",
+ tst_resm_(file, lineno, TINFO, "Failed to open FILE '%s'",
path);
return 1;
}
@@ -226,7 +226,7 @@ int file_printf(const char *file, const int lineno,
va_start(va, fmt);
if (vfprintf(f, fmt, va) < 0) {
- tst_resm_(file, lineno, TWARN, "Failed to print to FILE '%s'",
+ tst_resm_(file, lineno, TINFO, "Failed to print to FILE '%s'",
path);
goto err;
}
@@ -234,7 +234,7 @@ int file_printf(const char *file, const int lineno,
va_end(va);
if (fclose(f)) {
- tst_resm_(file, lineno, TWARN, "Failed to close FILE '%s'",
+ tst_resm_(file, lineno, TINFO, "Failed to close FILE '%s'",
path);
return 1;
}
@@ -243,7 +243,7 @@ int file_printf(const char *file, const int lineno,
err:
if (fclose(f)) {
- tst_resm_(file, lineno, TWARN, "Failed to close FILE '%s'",
+ tst_resm_(file, lineno, TINFO, "Failed to close FILE '%s'",
path);
}
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index af6dd0716..951e1b064 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -898,7 +898,16 @@ int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void),
const void *data)
{
int rval = -1;
+ char mpath[PATH_MAX];
+ if (realpath(target, mpath)) {
+ tst_resm_(file, lineno, TINFO,
+ "Mounting %s to %s fstyp=%s flags=%lx",
+ source, mpath, filesystemtype, mountflags);
+ } else {
+ tst_resm_(file, lineno, TINFO | TERRNO,
+ "Cannot resolve the absolute path of %s", target);
+ }
/*
* Don't try using the kernel's NTFS driver when mounting NTFS, since
* the kernel's NTFS driver doesn't have proper write support.
@@ -948,6 +957,14 @@ int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void),
const char *target)
{
int rval;
+ char mpath[PATH_MAX];
+
+ if (realpath(target, mpath)) {
+ tst_resm_(file, lineno, TINFO, "Umounting %s", mpath);
+ } else {
+ tst_resm_(file, lineno, TINFO | TERRNO,
+ "Cannot resolve the absolute path of %s", target);
+ }
rval = tst_umount(target);
diff --git a/lib/safe_net.c b/lib/safe_net.c
index 1717f0745..5dec0de11 100644
--- a/lib/safe_net.c
+++ b/lib/safe_net.c
@@ -469,6 +469,23 @@ int safe_gethostname(const char *file, const int lineno,
return rval;
}
+int safe_sethostname(const char *file, const int lineno,
+ const char *name, size_t size)
+{
+ int rval = sethostname(name, size);
+
+ if (rval == -1) {
+ tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
+ "sethostname(%p, %zu) failed", name, size);
+ } else if (rval) {
+ tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
+ "Invalid sethostname(%p, %zu) return value %d", name,
+ size, rval);
+ }
+
+ return rval;
+}
+
/*
* @return port in network byte order.
*/
diff --git a/lib/safe_pthread.c b/lib/safe_pthread.c
index d70bb8707..aeafe014c 100644
--- a/lib/safe_pthread.c
+++ b/lib/safe_pthread.c
@@ -106,3 +106,164 @@ int safe_pthread_barrier_init(const char *file, const int lineno,
return rval;
}
+
+int safe_pthread_mutexattr_init(const char *file, const int lineno,
+ pthread_mutexattr_t *attr)
+{
+ int ret;
+
+ ret = pthread_mutexattr_init(attr);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutexattr_init(%p) failed: %s",
+ attr, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutexattr_destroy(const char *file, const int lineno,
+ pthread_mutexattr_t *attr)
+{
+ int ret;
+
+ ret = pthread_mutexattr_destroy(attr);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutexattr_destroy(%p) failed: %s",
+ attr, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutexattr_settype(const char *file, const int lineno,
+ pthread_mutexattr_t *attr, int type)
+{
+ int ret;
+
+ ret = pthread_mutexattr_settype(attr, type);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutexattr_settype(%p, %d) failed: %s",
+ attr, type, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutex_init(const char *file, const int lineno,
+ pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+{
+ int ret;
+
+ ret = pthread_mutex_init(mutex, attr);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutex_init(%p, %p) failed: %s",
+ mutex, attr, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutex_destroy(const char *file, const int lineno,
+ pthread_mutex_t *mutex)
+{
+ int ret;
+
+ ret = pthread_mutex_destroy(mutex);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutex_destroy(%p) failed: %s",
+ mutex, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutex_lock(const char *file, const int lineno,
+ pthread_mutex_t *mutex)
+{
+ int ret;
+
+ ret = pthread_mutex_lock(mutex);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutex_lock(%p) failed: %s",
+ mutex, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutex_trylock(const char *file, const int lineno,
+ pthread_mutex_t *mutex)
+{
+ int ret;
+
+ ret = pthread_mutex_trylock(mutex);
+
+ if (ret && ret != EBUSY) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutex_trylock(%p) failed: %s",
+ mutex, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutex_timedlock(const char *file, const int lineno,
+ pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+ int ret;
+
+ ret = pthread_mutex_timedlock(mutex, abstime);
+
+ if (ret && ret != ETIMEDOUT) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutex_timedlock(%p, {%lld, %ld}) failed: %s",
+ mutex, (long long)abstime->tv_sec, abstime->tv_nsec,
+ tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_mutex_unlock(const char *file, const int lineno,
+ pthread_mutex_t *mutex)
+{
+ int ret;
+
+ ret = pthread_mutex_unlock(mutex);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_mutex_unlock(%p) failed: %s",
+ mutex, tst_strerrno(ret));
+ }
+
+ return ret;
+}
+
+int safe_pthread_kill(const char *file, const int lineno,
+ pthread_t thread, int sig)
+{
+ int ret;
+
+ ret = pthread_kill(thread, sig);
+
+ if (ret) {
+ tst_brk_(file, lineno, TBROK,
+ "pthread_kill(..., %d) failed: %s",
+ sig, tst_strerrno(ret));
+ }
+
+ return ret;
+}
diff --git a/lib/tests/.gitignore b/lib/tests/.gitignore
new file mode 100644
index 000000000..1d880c1b7
--- /dev/null
+++ b/lib/tests/.gitignore
@@ -0,0 +1,17 @@
+/tst_tmpdir_test
+/tst_checkpoint
+/tst_checkpoint_wait_timeout
+/tst_checkpoint_wake_timeout
+/tst_process_state
+/tst_cleanup_once
+/tst_safe_macros
+/tst_strsig
+/tst_strerrno
+/tst_fs_fill_subdirs
+/tst_fs_fill_hardlinks
+/tst_device
+/tst_record_childstatus
+/trerrno
+/tst_dataroot01
+/tst_dataroot02
+/tst_dataroot03
diff --git a/lib/tests/tst_tmpdir_test.c b/lib/tests/tst_tmpdir_test.c
index f394893a4..774537587 100644
--- a/lib/tests/tst_tmpdir_test.c
+++ b/lib/tests/tst_tmpdir_test.c
@@ -26,7 +26,7 @@
*
* This program creates and deletes a temporary file in order to test
* the functionality of the tst_tmpdir functionality.
- * On successfull completion it prints the message:
+ * On successful completion it prints the message:
* "Test completed successfully!"
*/
diff --git a/lib/tlibio.c b/lib/tlibio.c
index 79883913a..2ecdbb42a 100644
--- a/lib/tlibio.c
+++ b/lib/tlibio.c
@@ -539,6 +539,10 @@ int lio_write_buffer(int fd, /* open file descriptor */
long wrd) /* to allow future features, use zero for now */
{
int ret = 0; /* syscall return or used to get random method */
+ /* as we cycle writes in case of partial writes, we have to report up
+ * total bytes written
+ */
+ int totally_written = 0;
char *io_type; /* Holds string of type of io */
int omethod = method;
int listio_cmd; /* Holds the listio/lio_listio cmd */
@@ -745,13 +749,14 @@ int lio_write_buffer(int fd, /* open file descriptor */
fd, size, ret);
size -= ret;
buffer += ret;
+ totally_written += ret;
} else {
if (Debug_level > 1)
printf
("DEBUG %s/%d: write completed without error (ret %d)\n",
__FILE__, __LINE__, ret);
- return ret;
+ return totally_written + ret;
}
}
wait4sync_io(fd, 0);
@@ -1109,6 +1114,10 @@ int lio_read_buffer(int fd, /* open file descriptor */
long wrd) /* to allow future features, use zero for now */
{
int ret = 0; /* syscall return or used to get random method */
+ /* as we cycle reads in case of partial reads, we have to report up
+ * total bytes read
+ */
+ int totally_read = 0;
char *io_type; /* Holds string of type of io */
int listio_cmd; /* Holds the listio/lio_listio cmd */
int omethod = method;
@@ -1320,13 +1329,14 @@ int lio_read_buffer(int fd, /* open file descriptor */
fd, size, ret);
size -= ret;
buffer += ret;
+ totally_read += ret;
} else {
if (Debug_level > 1)
printf
("DEBUG %s/%d: read completed without error (ret %d)\n",
__FILE__, __LINE__, ret);
- return ret;
+ return totally_read + ret;
}
}
wait4sync_io(fd, 1);
diff --git a/lib/tst_bool_expr.c b/lib/tst_bool_expr.c
index 15825e364..d7983e7b0 100644
--- a/lib/tst_bool_expr.c
+++ b/lib/tst_bool_expr.c
@@ -9,7 +9,7 @@
* tokenizer runs twice and we only count number of tokens in the first pass in
* order to simplify the memory allocation.
*
- * Secondly the the expression is transformed to a postfix (RPN) notation by
+ * Secondly the expression is transformed to a postfix (RPN) notation by
* the shunting yard algorithm and the correctness of the expression is checked
* during the transformation as well. The fact that parenthesis are matched is
* asserted by the shunting yard algorithm itself while the rest is checked
diff --git a/lib/tst_buffers.c b/lib/tst_buffers.c
index b8b597a12..b0bd359eb 100644
--- a/lib/tst_buffers.c
+++ b/lib/tst_buffers.c
@@ -5,6 +5,7 @@
#include <sys/mman.h>
#include <stdlib.h>
+#include <stdio.h>
#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"
@@ -76,6 +77,25 @@ void *tst_alloc(size_t size)
return ret + map->buf_shift;
}
+char *tst_aprintf(const char *fmt, ...)
+{
+ va_list va;
+ int len;
+ char *ret;
+
+ va_start(va, fmt);
+ len = vsnprintf(NULL, 0, fmt, va)+1;
+ va_end(va);
+
+ ret = tst_alloc(len);
+
+ va_start(va, fmt);
+ vsprintf(ret, fmt, va);
+ va_end(va);
+
+ return ret;
+}
+
static int count_iovec(int *sizes)
{
int ret = 0;
@@ -115,15 +135,17 @@ void tst_buffers_alloc(struct tst_buffers bufs[])
for (i = 0; bufs[i].ptr; i++) {
if (bufs[i].size)
*((void**)bufs[i].ptr) = tst_alloc(bufs[i].size);
- else
+ else if (bufs[i].iov_sizes)
*((void**)bufs[i].ptr) = tst_iovec_alloc(bufs[i].iov_sizes);
+ else
+ *((void**)bufs[i].ptr) = tst_strdup(bufs[i].str);
}
}
char *tst_strdup(const char *str)
{
- size_t len = strlen(str);
- char *ret = tst_alloc(len + 1);
+ char *ret = tst_alloc(strlen(str) + 1);
+
return strcpy(ret, str);
}
diff --git a/lib/tst_cgroup.c b/lib/tst_cgroup.c
index 50699bc63..6e9ab372d 100644
--- a/lib/tst_cgroup.c
+++ b/lib/tst_cgroup.c
@@ -94,9 +94,10 @@ enum cgroup_ctrl_indx {
CTRL_MISC,
CTRL_PERFEVENT,
CTRL_DEBUG,
- CTRL_RDMA
+ CTRL_RDMA,
+ CTRL_BASE
};
-#define CTRLS_MAX CTRL_RDMA
+#define CTRLS_MAX CTRL_BASE
/* At most we can have one cgroup V1 tree for each controller and one
* (empty) v2 tree.
@@ -166,6 +167,7 @@ static const struct cgroup_file cgroup_ctrl_files[] = {
{ "cgroup.controllers", NULL, 0 },
{ "cgroup.subtree_control", NULL, 0 },
{ "cgroup.clone_children", "cgroup.clone_children", 0 },
+ { "cgroup.kill", NULL, 0 },
{ }
};
@@ -258,6 +260,10 @@ static const struct cgroup_file rdma_ctrl_files[] = {
{ }
};
+static const struct cgroup_file base_ctrl_files[] = {
+ { }
+};
+
#define CTRL_NAME_MAX 31
#define CGROUP_CTRL_MEMBER(x, y)[y] = { .ctrl_name = #x, .files = \
x ## _ctrl_files, .ctrl_indx = y, NULL, 0 }
@@ -281,6 +287,7 @@ static struct cgroup_ctrl controllers[] = {
CGROUP_CTRL_MEMBER(perf_event, CTRL_PERFEVENT),
CGROUP_CTRL_MEMBER(debug, CTRL_DEBUG),
CGROUP_CTRL_MEMBER(rdma, CTRL_RDMA),
+ CGROUP_CTRL_MEMBER(base, CTRL_BASE),
{ }
};
@@ -376,6 +383,9 @@ static void cgroup_dir_mk(const struct cgroup_dir *const parent,
tst_brk(TCONF | TERRNO,
"Lack permission to make '%s/%s'; premake it or run as root",
dpath, dir_name);
+ } else if (errno == EROFS) {
+ tst_brk(TCONF | TERRNO, "'%s/%s' must not be read-only",
+ dpath, dir_name);
} else {
tst_brk(TBROK | TERRNO,
"mkdirat(%d<%s>, '%s', 0777)",
@@ -420,12 +430,28 @@ void tst_cg_print_config(void)
}
__attribute__ ((nonnull, warn_unused_result))
-static struct cgroup_ctrl *cgroup_find_ctrl(const char *const ctrl_name)
+static struct cgroup_ctrl *cgroup_find_ctrl(const char *const ctrl_name,
+ unsigned int strict)
{
struct cgroup_ctrl *ctrl;
+ int l = 0;
+ char c = ctrl_name[l];
+
+ while (c == '_' || (c >= 'a' && c <= 'z'))
+ c = ctrl_name[++l];
+
+ if (l > 32 && strict)
+ tst_res(TWARN, "Subsys name len greater than max known value of MAX_CGROUP_TYPE_NAMELEN: %d > 32", l);
+
+ if (!(c == '\n' || c == '\0')) {
+ if (!strict)
+ return NULL;
+
+ tst_brk(TBROK, "Unexpected char in %s: %c", ctrl_name, c);
+ }
for_each_ctrl(ctrl) {
- if (!strcmp(ctrl_name, ctrl->ctrl_name))
+ if (!strncmp(ctrl_name, ctrl->ctrl_name, l))
return ctrl;
}
@@ -458,7 +484,7 @@ static void cgroup_parse_config_line(const char *const config_entry)
if (vars_read != 7)
tst_brk(TBROK, "Incorrect number of vars read from config. Config possibly malformed?");
- ctrl = cgroup_find_ctrl(ctrl_name);
+ ctrl = cgroup_find_ctrl(ctrl_name, 1);
if (!ctrl)
tst_brk(TBROK, "Could not find ctrl from config. Ctrls changing between calls?");
@@ -551,7 +577,7 @@ static void cgroup_root_scan(const char *const mnt_type,
SAFE_FILE_READAT(mnt_dfd, "cgroup.controllers", buf, sizeof(buf));
for (tok = strtok(buf, " "); tok; tok = strtok(NULL, " ")) {
- const_ctrl = cgroup_find_ctrl(tok);
+ const_ctrl = cgroup_find_ctrl(tok, 1);
if (const_ctrl)
add_ctrl(&ctrl_field, const_ctrl);
}
@@ -568,7 +594,7 @@ static void cgroup_root_scan(const char *const mnt_type,
v1:
for (tok = strtok(mnt_opts, ","); tok; tok = strtok(NULL, ",")) {
- const_ctrl = cgroup_find_ctrl(tok);
+ const_ctrl = cgroup_find_ctrl(tok, 0);
if (const_ctrl)
add_ctrl(&ctrl_field, const_ctrl);
@@ -795,8 +821,12 @@ void tst_cg_require(const char *const ctrl_name,
const struct tst_cg_opts *options)
{
const char *const cgsc = "cgroup.subtree_control";
- struct cgroup_ctrl *const ctrl = cgroup_find_ctrl(ctrl_name);
+ struct cgroup_ctrl *const ctrl = cgroup_find_ctrl(ctrl_name, 1);
struct cgroup_root *root;
+ int base = !strcmp(ctrl->ctrl_name, "base");
+
+ if (base && options->needs_ver != TST_CG_V2)
+ tst_brk(TCONF, "Base control only support needs_ver TST_CG_V2!");
if (!ctrl) {
tst_brk(TBROK, "'%s' controller is unknown to LTP", ctrl_name);
@@ -826,6 +856,9 @@ void tst_cg_require(const char *const ctrl_name,
if (options->needs_ver != TST_CG_V2)
cgroup_mount_v1(ctrl);
+ if (base)
+ ctrl->ctrl_root = roots;
+
if (!ctrl->ctrl_root) {
tst_brk(TCONF,
"'%s' controller required, but not available",
@@ -848,7 +881,7 @@ mkdirs:
ctrl->ctrl_name);
}
- if (cgroup_ctrl_on_v2(ctrl)) {
+ if (cgroup_ctrl_on_v2(ctrl) && !base) {
if (root->we_mounted_it) {
SAFE_FILE_PRINTFAT(root->mnt_dir.dir_fd,
cgsc, "+%s", ctrl->ctrl_name);
@@ -863,15 +896,17 @@ mkdirs:
else
root->ltp_dir.ctrl_field |= root->mnt_dir.ctrl_field;
- if (cgroup_ctrl_on_v2(ctrl)) {
- SAFE_FILE_PRINTFAT(root->ltp_dir.dir_fd,
- cgsc, "+%s", ctrl->ctrl_name);
- } else {
- SAFE_FILE_PRINTFAT(root->ltp_dir.dir_fd,
- "cgroup.clone_children", "%d", 1);
+ if (!base) {
+ if (cgroup_ctrl_on_v2(ctrl)) {
+ SAFE_FILE_PRINTFAT(root->ltp_dir.dir_fd,
+ cgsc, "+%s", ctrl->ctrl_name);
+ } else {
+ SAFE_FILE_PRINTFAT(root->ltp_dir.dir_fd,
+ "cgroup.clone_children", "%d", 1);
- if (ctrl->ctrl_indx == CTRL_CPUSET)
- cgroup_copy_cpuset(root);
+ if (ctrl->ctrl_indx == CTRL_CPUSET)
+ cgroup_copy_cpuset(root);
+ }
}
cgroup_dir_mk(&root->ltp_dir, cgroup_ltp_drain_dir, &root->drain_dir);
@@ -996,7 +1031,8 @@ void tst_cg_cleanup(void)
}
for_each_ctrl(ctrl) {
- if (!cgroup_ctrl_on_v2(ctrl) || !ctrl->ctrl_root->we_mounted_it)
+ if (!cgroup_ctrl_on_v2(ctrl) || !ctrl->ctrl_root->we_mounted_it
+ || !strcmp(ctrl->ctrl_name, "base"))
continue;
SAFE_FILE_PRINTFAT(ctrl->ctrl_root->mnt_dir.dir_fd,
@@ -1049,8 +1085,10 @@ static void cgroup_group_add_dir(const struct tst_cg_group *const parent,
if (!parent || dir->dir_root->ver == TST_CG_V1)
continue;
- SAFE_CG_PRINTF(parent, "cgroup.subtree_control",
- "+%s", ctrl->ctrl_name);
+ if (strcmp(ctrl->ctrl_name, "base")) {
+ SAFE_CG_PRINTF(parent, "cgroup.subtree_control",
+ "+%s", ctrl->ctrl_name);
+ }
}
for (i = 0; cg->dirs[i]; i++)
@@ -1093,6 +1131,14 @@ const char *tst_cg_group_name(const struct tst_cg_group *const cg)
return cg->group_name;
}
+int tst_cg_group_unified_dir_fd(const struct tst_cg_group *const cg)
+{
+ if(cg->dirs_by_ctrl[0])
+ return cg->dirs_by_ctrl[0]->dir_fd;
+
+ return -1;
+}
+
struct tst_cg_group *tst_cg_group_rm(struct tst_cg_group *const cg)
{
struct cgroup_dir **dir;
@@ -1131,7 +1177,7 @@ static const struct cgroup_file *cgroup_file_find(const char *const file,
memcpy(ctrl_name, file_name, len);
ctrl_name[len] = '\0';
- ctrl = cgroup_find_ctrl(ctrl_name);
+ ctrl = cgroup_find_ctrl(ctrl_name, 1);
if (!ctrl) {
tst_brk_(file, lineno, TBROK,
@@ -1158,7 +1204,7 @@ enum tst_cg_ver tst_cg_ver(const char *const file, const int lineno,
const struct tst_cg_group *const cg,
const char *const ctrl_name)
{
- const struct cgroup_ctrl *const ctrl = cgroup_find_ctrl(ctrl_name);
+ const struct cgroup_ctrl *const ctrl = cgroup_find_ctrl(ctrl_name, 1);
const struct cgroup_dir *dir;
if (!strcmp(ctrl_name, "cgroup")) {
diff --git a/lib/tst_clocks.c b/lib/tst_clocks.c
index 0417802fc..29f4b420c 100644
--- a/lib/tst_clocks.c
+++ b/lib/tst_clocks.c
@@ -17,8 +17,9 @@ typedef int (*mysyscall)(clockid_t clk_id, void *ts);
int syscall_supported_by_kernel(long sysnr)
{
int ret;
+ struct __kernel_timespec foo;
- ret = syscall(sysnr, 0, NULL);
+ ret = syscall(sysnr, 0, &foo);
if (ret == -1 && errno == ENOSYS)
return 0;
diff --git a/lib/tst_clone.c b/lib/tst_clone.c
index ecc84408c..2aa00beb1 100644
--- a/lib/tst_clone.c
+++ b/lib/tst_clone.c
@@ -15,6 +15,7 @@ pid_t tst_clone(const struct tst_clone_args *tst_args)
struct clone_args args = {
.flags = tst_args->flags,
.exit_signal = tst_args->exit_signal,
+ .cgroup = tst_args->cgroup,
};
int flags;
pid_t pid = -1;
diff --git a/lib/tst_fill_fs.c b/lib/tst_fill_fs.c
index b9d29755a..5e8cf9197 100644
--- a/lib/tst_fill_fs.c
+++ b/lib/tst_fill_fs.c
@@ -73,12 +73,30 @@ void fill_random(const char *path, int verbose)
void fill_flat_vec(const char *path, int verbose)
{
- int dir = SAFE_OPEN(path, O_PATH | O_DIRECTORY);
- int fd = SAFE_OPENAT(dir, "AOF", O_WRONLY | O_CREAT, 0600);
+ int dir, fd;
struct iovec iov[512];
int iovcnt = ARRAY_SIZE(iov);
int retries = 3;
+ dir = open(path, O_PATH | O_DIRECTORY);
+ if (dir == -1) {
+ if (errno == ENOSPC) {
+ tst_res(TINFO | TERRNO, "open()");
+ return;
+ }
+ tst_brk(TBROK | TERRNO, "open(%s, %d) failed", path, O_PATH | O_DIRECTORY);
+ }
+
+ fd = openat(dir, "AOF", O_WRONLY | O_CREAT, 0600);
+ if (fd == -1) {
+ if (errno == ENOSPC) {
+ tst_res(TINFO | TERRNO, "openat()");
+ return;
+ }
+ tst_brk(TBROK | TERRNO, "openat(%d, %d, 0600) failed for path %s",
+ dir, O_PATH | O_DIRECTORY, path);
+ }
+
SAFE_CLOSE(dir);
for (int i = 0; i < iovcnt; i++) {
diff --git a/lib/tst_fs_setup.c b/lib/tst_fs_setup.c
index 6b93483de..aaa8f3bc9 100644
--- a/lib/tst_fs_setup.c
+++ b/lib/tst_fs_setup.c
@@ -24,7 +24,7 @@ void create_overlay_dirs(void)
closedir(dir);
}
-int mount_overlay(const char *file, const int lineno, int skip)
+int mount_overlay(const char *file, const int lineno, int strict)
{
int ret;
@@ -35,14 +35,14 @@ int mount_overlay(const char *file, const int lineno, int skip)
return 0;
if (errno == ENODEV) {
- if (skip) {
+ if (strict) {
tst_brk_(file, lineno, TCONF,
TST_FS_SETUP_OVERLAYFS_MSG);
} else {
tst_res_(file, lineno, TINFO,
TST_FS_SETUP_OVERLAYFS_MSG);
}
- } else {
+ } else if (strict) {
tst_brk_(file, lineno, TBROK | TERRNO,
"overlayfs mount failed");
}
diff --git a/lib/tst_hugepage.c b/lib/tst_hugepage.c
index 728a8c3ec..d2e70a955 100644
--- a/lib/tst_hugepage.c
+++ b/lib/tst_hugepage.c
@@ -47,6 +47,7 @@ unsigned long tst_reserve_hugepages(struct tst_hugepage *hp)
}
SAFE_FILE_PRINTF("/proc/sys/vm/drop_caches", "3");
+ SAFE_FILE_PRINTF("/proc/sys/vm/compact_memory", "1");
if (hp->policy == TST_NEEDS) {
tst_hugepages += SAFE_READ_MEMINFO("HugePages_Total:");
goto set_hugepages;
diff --git a/lib/tst_kernel.c b/lib/tst_kernel.c
index ecf4b917e..4b75ceadb 100644
--- a/lib/tst_kernel.c
+++ b/lib/tst_kernel.c
@@ -85,12 +85,12 @@ int tst_kernel_bits(void)
#endif /* __ANDROID__ */
tst_resm(TINFO, "uname.machine=%s kernel is %ibit",
- buf.machine, kernel_bits);
+ buf.machine, kernel_bits);
return kernel_bits;
}
-static int tst_search_driver(const char *driver, const char *file)
+static int tst_search_driver_(const char *driver, const char *file)
{
struct stat st;
char buf[PATH_MAX];
@@ -118,6 +118,7 @@ static int tst_search_driver(const char *driver, const char *file)
/* always search for x86_64 */
char *fix = strstr(driver, "x86-64");
+
if (fix)
fix[3] = '_';
@@ -144,28 +145,19 @@ static int tst_search_driver(const char *driver, const char *file)
return ret;
}
-static int tst_check_driver_(const char *driver)
-{
- if (!tst_search_driver(driver, "modules.dep") ||
- !tst_search_driver(driver, "modules.builtin"))
- return 0;
-
- return -1;
-}
-
-int tst_check_driver(const char *driver)
+static int tst_search_driver(const char *driver, const char *file)
{
#ifdef __ANDROID__
/*
* Android may not have properly installed modules.* files. We could
- * search modules in /system/lib/modules, but to to determine built-in
+ * search modules in /system/lib/modules, but to determine built-in
* drivers we need modules.builtin. Therefore assume all drivers are
* available.
*/
return 0;
#endif
- if (!tst_check_driver_(driver))
+ if (!tst_search_driver_(driver, file))
return 0;
int ret = -1;
@@ -183,9 +175,26 @@ int tst_check_driver(const char *driver)
while ((ix = strchr(ix, find)))
*ix++ = replace;
- ret = tst_check_driver_(driver2);
+ ret = tst_search_driver_(driver2, file);
free(driver2);
}
return ret;
}
+
+int tst_check_builtin_driver(const char *driver)
+{
+ if (!tst_search_driver(driver, "modules.builtin"))
+ return 0;
+
+ return -1;
+}
+
+int tst_check_driver(const char *driver)
+{
+ if (!tst_search_driver(driver, "modules.dep") ||
+ !tst_search_driver(driver, "modules.builtin"))
+ return 0;
+
+ return -1;
+}
diff --git a/lib/tst_kvercmp.c b/lib/tst_kvercmp.c
index 552920fac..9e1a511af 100644
--- a/lib/tst_kvercmp.c
+++ b/lib/tst_kvercmp.c
@@ -92,8 +92,8 @@ int tst_kvcmp(const char *cur_kver, int r1, int r2, int r3)
cur_kver);
}
- testver = (r1 << 16) + (r2 << 8) + r3;
- currver = (a1 << 16) + (a2 << 8) + a3;
+ testver = (r1 << 20) + (r2 << 10) + r3;
+ currver = (a1 << 20) + (a2 << 10) + a3;
return currver - testver;
}
diff --git a/lib/tst_lockdown.c b/lib/tst_lockdown.c
index 26a57b6a1..38d830886 100644
--- a/lib/tst_lockdown.c
+++ b/lib/tst_lockdown.c
@@ -14,47 +14,59 @@
#include "tst_lockdown.h"
#include "tst_private.h"
-#define EFIVAR_SECUREBOOT "/sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c"
+#if defined(__powerpc64__) || defined(__ppc64__)
+# define SECUREBOOT_VAR "/proc/device-tree/ibm,secure-boot"
+# define VAR_DATA_SIZE 4
+#else
+# define SECUREBOOT_VAR "/sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c"
+# define VAR_DATA_SIZE 5
+#endif
int tst_secureboot_enabled(void)
{
int fd;
char data[5];
- if (access(EFIVAR_SECUREBOOT, F_OK)) {
- tst_res(TINFO, "Efivar FS not available");
+ if (access(SECUREBOOT_VAR, F_OK)) {
+ tst_res(TINFO, "SecureBoot sysfs file not available");
return -1;
}
- fd = open(EFIVAR_SECUREBOOT, O_RDONLY);
+ fd = open(SECUREBOOT_VAR, O_RDONLY);
if (fd == -1) {
tst_res(TINFO | TERRNO,
- "Cannot open SecureBoot Efivar sysfile");
+ "Cannot open SecureBoot file");
return -1;
} else if (fd < 0) {
tst_brk(TBROK | TERRNO, "Invalid open() return value %d", fd);
return -1;
}
-
- SAFE_READ(1, fd, data, 5);
+ SAFE_READ(1, fd, data, VAR_DATA_SIZE);
SAFE_CLOSE(fd);
- tst_res(TINFO, "SecureBoot: %s", data[4] ? "on" : "off");
- return data[4];
+ tst_res(TINFO, "SecureBoot: %s", data[VAR_DATA_SIZE - 1] ? "on" : "off");
+ return data[VAR_DATA_SIZE - 1];
}
int tst_lockdown_enabled(void)
{
char line[BUFSIZ];
FILE *file;
+ int ret;
if (access(PATH_LOCKDOWN, F_OK) != 0) {
char flag;
- flag = tst_kconfig_get("CONFIG_EFI_SECURE_BOOT_LOCK_DOWN");
+ /* SecureBoot enabled could mean integrity lockdown (non-mainline version) */
+#if defined(__powerpc64__) || defined(__ppc64__)
+ flag = tst_kconfig_get("CONFIG_SECURITY_LOCKDOWN_LSM") == 'y';
+ flag |= tst_kconfig_get("CONFIG_SECURITY_LOCKDOWN_LSM_EARLY") == 'y';
+#else
+ flag = tst_kconfig_get("CONFIG_EFI_SECURE_BOOT_LOCK_DOWN") == 'y';
+ flag |= tst_kconfig_get("CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT") == 'y';
+#endif
- /* SecureBoot enabled could mean integrity lockdown */
- if (flag == 'y' && tst_secureboot_enabled() > 0)
+ if (flag && tst_secureboot_enabled() > 0)
return 1;
tst_res(TINFO, "Unable to determine system lockdown state");
@@ -66,5 +78,8 @@ int tst_lockdown_enabled(void)
tst_brk(TBROK | TERRNO, "fgets %s", PATH_LOCKDOWN);
SAFE_FCLOSE(file);
- return (strstr(line, "[none]") == NULL);
+ ret = strstr(line, "[none]") == NULL;
+ tst_res(TINFO, "Kernel lockdown: %s", ret ? "on" : "off");
+
+ return ret;
}
diff --git a/lib/tst_memutils.c b/lib/tst_memutils.c
index 6fc9f6a93..c5382ff10 100644
--- a/lib/tst_memutils.c
+++ b/lib/tst_memutils.c
@@ -95,6 +95,15 @@ long long tst_available_mem(void)
return mem_available;
}
+long long tst_available_swap(void)
+{
+ unsigned long long swap_available = 0;
+
+ FILE_LINES_SCANF("/proc/meminfo", "SwapFree: %llu", &swap_available);
+
+ return swap_available;
+}
+
static int has_caps(void)
{
struct tst_cap_user_header hdr = {
diff --git a/lib/tst_netdevice.c b/lib/tst_netdevice.c
index 4a0442932..dba44c623 100644
--- a/lib/tst_netdevice.c
+++ b/lib/tst_netdevice.c
@@ -7,6 +7,7 @@
#include <linux/veth.h>
#include <sys/socket.h>
#include <net/if.h>
+#include <linux/pkt_sched.h>
#include "lapi/rtnetlink.h"
#define TST_NO_DEFAULT_MAIN
@@ -97,7 +98,7 @@ int tst_netdev_set_state(const char *file, const int lineno,
return ret;
}
-int tst_create_veth_pair(const char *file, const int lineno,
+int tst_create_veth_pair(const char *file, const int lineno, int strict,
const char *ifname1, const char *ifname2)
{
int ret;
@@ -147,7 +148,7 @@ int tst_create_veth_pair(const char *file, const int lineno,
ret = tst_rtnl_send_validate(file, lineno, ctx);
tst_rtnl_destroy_context(file, lineno, ctx);
- if (!ret) {
+ if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to create veth interfaces %s+%s: %s", ifname1,
ifname2, tst_strerrno(tst_rtnl_errno));
@@ -156,7 +157,7 @@ int tst_create_veth_pair(const char *file, const int lineno,
return ret;
}
-int tst_netdev_add_device(const char *file, const int lineno,
+int tst_netdev_add_device(const char *file, const int lineno, int strict,
const char *ifname, const char *devtype)
{
int ret;
@@ -191,7 +192,7 @@ int tst_netdev_add_device(const char *file, const int lineno,
ret = tst_rtnl_send_validate(file, lineno, ctx);
tst_rtnl_destroy_context(file, lineno, ctx);
- if (!ret) {
+ if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to create %s device %s: %s", devtype, ifname,
tst_strerrno(tst_rtnl_errno));
@@ -200,7 +201,7 @@ int tst_netdev_add_device(const char *file, const int lineno,
return ret;
}
-int tst_netdev_remove_device(const char *file, const int lineno,
+int tst_netdev_remove_device(const char *file, const int lineno, int strict,
const char *ifname)
{
struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
@@ -226,7 +227,7 @@ int tst_netdev_remove_device(const char *file, const int lineno,
ret = tst_rtnl_send_validate(file, lineno, ctx);
tst_rtnl_destroy_context(file, lineno, ctx);
- if (!ret) {
+ if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to remove netdevice %s: %s", ifname,
tst_strerrno(tst_rtnl_errno));
@@ -235,7 +236,7 @@ int tst_netdev_remove_device(const char *file, const int lineno,
return ret;
}
-static int modify_address(const char *file, const int lineno,
+static int modify_address(const char *file, const int lineno, int strict,
unsigned int action, unsigned int nl_flags, const char *ifname,
unsigned int family, const void *address, unsigned int prefix,
size_t addrlen, uint32_t addr_flags)
@@ -276,7 +277,7 @@ static int modify_address(const char *file, const int lineno,
ret = tst_rtnl_send_validate(file, lineno, ctx);
tst_rtnl_destroy_context(file, lineno, ctx);
- if (!ret) {
+ if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to modify %s network address: %s", ifname,
tst_strerrno(tst_rtnl_errno));
@@ -285,40 +286,40 @@ static int modify_address(const char *file, const int lineno,
return ret;
}
-int tst_netdev_add_address(const char *file, const int lineno,
+int tst_netdev_add_address(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *address,
unsigned int prefix, size_t addrlen, unsigned int flags)
{
- return modify_address(file, lineno, RTM_NEWADDR,
+ return modify_address(file, lineno, strict, RTM_NEWADDR,
NLM_F_CREATE | NLM_F_EXCL, ifname, family, address, prefix,
addrlen, flags);
}
-int tst_netdev_add_address_inet(const char *file, const int lineno,
+int tst_netdev_add_address_inet(const char *file, const int lineno, int strict,
const char *ifname, in_addr_t address, unsigned int prefix,
unsigned int flags)
{
- return tst_netdev_add_address(file, lineno, ifname, AF_INET,
+ return tst_netdev_add_address(file, lineno, strict, ifname, AF_INET,
&address, prefix, sizeof(address), flags);
}
-int tst_netdev_remove_address(const char *file, const int lineno,
+int tst_netdev_remove_address(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *address,
size_t addrlen)
{
- return modify_address(file, lineno, RTM_DELADDR, 0, ifname, family,
- address, 0, addrlen, 0);
+ return modify_address(file, lineno, strict, RTM_DELADDR, 0, ifname,
+ family, address, 0, addrlen, 0);
}
int tst_netdev_remove_address_inet(const char *file, const int lineno,
- const char *ifname, in_addr_t address)
+ int strict, const char *ifname, in_addr_t address)
{
- return tst_netdev_remove_address(file, lineno, ifname, AF_INET,
+ return tst_netdev_remove_address(file, lineno, strict, ifname, AF_INET,
&address, sizeof(address));
}
-static int change_ns(const char *file, const int lineno, const char *ifname,
- unsigned short attr, uint32_t value)
+static int change_ns(const char *file, const int lineno, int strict,
+ const char *ifname, unsigned short attr, uint32_t value)
{
struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
struct tst_rtnl_context *ctx;
@@ -332,6 +333,9 @@ static int change_ns(const char *file, const int lineno, const char *ifname,
ctx = create_request(file, lineno, RTM_NEWLINK, 0, &info, sizeof(info));
+ if (!ctx)
+ return 0;
+
if (!tst_rtnl_add_attr_string(file, lineno, ctx, IFLA_IFNAME, ifname)) {
tst_rtnl_destroy_context(file, lineno, ctx);
return 0;
@@ -346,7 +350,7 @@ static int change_ns(const char *file, const int lineno, const char *ifname,
ret = tst_rtnl_send_validate(file, lineno, ctx);
tst_rtnl_destroy_context(file, lineno, ctx);
- if (!ret) {
+ if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to move %s to another namespace: %s", ifname,
tst_strerrno(tst_rtnl_errno));
@@ -355,23 +359,23 @@ static int change_ns(const char *file, const int lineno, const char *ifname,
return ret;
}
-int tst_netdev_change_ns_fd(const char *file, const int lineno,
+int tst_netdev_change_ns_fd(const char *file, const int lineno, int strict,
const char *ifname, int nsfd)
{
- return change_ns(file, lineno, ifname, IFLA_NET_NS_FD, nsfd);
+ return change_ns(file, lineno, strict, ifname, IFLA_NET_NS_FD, nsfd);
}
-int tst_netdev_change_ns_pid(const char *file, const int lineno,
+int tst_netdev_change_ns_pid(const char *file, const int lineno, int strict,
const char *ifname, pid_t nspid)
{
- return change_ns(file, lineno, ifname, IFLA_NET_NS_PID, nspid);
+ return change_ns(file, lineno, strict, ifname, IFLA_NET_NS_PID, nspid);
}
-static int modify_route(const char *file, const int lineno, unsigned int action,
- unsigned int flags, const char *ifname, unsigned int family,
- const void *srcaddr, unsigned int srcprefix, size_t srclen,
- const void *dstaddr, unsigned int dstprefix, size_t dstlen,
- const void *gateway, size_t gatewaylen)
+static int modify_route(const char *file, const int lineno, int strict,
+ unsigned int action, unsigned int flags, const char *ifname,
+ unsigned int family, const void *srcaddr, unsigned int srcprefix,
+ size_t srclen, const void *dstaddr, unsigned int dstprefix,
+ size_t dstlen, const void *gateway, size_t gatewaylen)
{
struct tst_rtnl_context *ctx;
int ret;
@@ -411,6 +415,9 @@ static int modify_route(const char *file, const int lineno, unsigned int action,
ctx = create_request(file, lineno, action, flags, &info, sizeof(info));
+ if (!ctx)
+ return 0;
+
if (srcaddr && !tst_rtnl_add_attr(file, lineno, ctx, RTA_SRC, srcaddr,
srclen)) {
tst_rtnl_destroy_context(file, lineno, ctx);
@@ -438,7 +445,7 @@ static int modify_route(const char *file, const int lineno, unsigned int action,
ret = tst_rtnl_send_validate(file, lineno, ctx);
tst_rtnl_destroy_context(file, lineno, ctx);
- if (!ret) {
+ if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to modify network route: %s",
tst_strerrno(tst_rtnl_errno));
@@ -447,7 +454,7 @@ static int modify_route(const char *file, const int lineno, unsigned int action,
return ret;
}
-static int modify_route_inet(const char *file, const int lineno,
+static int modify_route_inet(const char *file, const int lineno, int strict,
unsigned int action, unsigned int flags, const char *ifname,
in_addr_t srcaddr, unsigned int srcprefix, in_addr_t dstaddr,
unsigned int dstprefix, in_addr_t gateway)
@@ -470,45 +477,165 @@ static int modify_route_inet(const char *file, const int lineno,
gwlen = sizeof(gateway);
}
- return modify_route(file, lineno, action, flags, ifname, AF_INET, src,
- srcprefix, srclen, dst, dstprefix, dstlen, gw, gwlen);
+ return modify_route(file, lineno, strict, action, flags, ifname,
+ AF_INET, src, srcprefix, srclen, dst, dstprefix, dstlen, gw,
+ gwlen);
}
-int tst_netdev_add_route(const char *file, const int lineno,
+int tst_netdev_add_route(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *srcaddr,
unsigned int srcprefix, size_t srclen, const void *dstaddr,
unsigned int dstprefix, size_t dstlen, const void *gateway,
size_t gatewaylen)
{
- return modify_route(file, lineno, RTM_NEWROUTE,
+ return modify_route(file, lineno, strict, RTM_NEWROUTE,
NLM_F_CREATE | NLM_F_EXCL, ifname, family, srcaddr, srcprefix,
srclen, dstaddr, dstprefix, dstlen, gateway, gatewaylen);
}
-int tst_netdev_add_route_inet(const char *file, const int lineno,
+int tst_netdev_add_route_inet(const char *file, const int lineno, int strict,
const char *ifname, in_addr_t srcaddr, unsigned int srcprefix,
in_addr_t dstaddr, unsigned int dstprefix, in_addr_t gateway)
{
- return modify_route_inet(file, lineno, RTM_NEWROUTE,
+ return modify_route_inet(file, lineno, strict, RTM_NEWROUTE,
NLM_F_CREATE | NLM_F_EXCL, ifname, srcaddr, srcprefix, dstaddr,
dstprefix, gateway);
}
-int tst_netdev_remove_route(const char *file, const int lineno,
+int tst_netdev_remove_route(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *srcaddr,
unsigned int srcprefix, size_t srclen, const void *dstaddr,
unsigned int dstprefix, size_t dstlen, const void *gateway,
size_t gatewaylen)
{
- return modify_route(file, lineno, RTM_DELROUTE, 0, ifname, family,
- srcaddr, srcprefix, srclen, dstaddr, dstprefix, dstlen,
+ return modify_route(file, lineno, strict, RTM_DELROUTE, 0, ifname,
+ family, srcaddr, srcprefix, srclen, dstaddr, dstprefix, dstlen,
gateway, gatewaylen);
}
int tst_netdev_remove_route_inet(const char *file, const int lineno,
- const char *ifname, in_addr_t srcaddr, unsigned int srcprefix,
- in_addr_t dstaddr, unsigned int dstprefix, in_addr_t gateway)
+ int strict, const char *ifname, in_addr_t srcaddr,
+ unsigned int srcprefix, in_addr_t dstaddr, unsigned int dstprefix,
+ in_addr_t gateway)
{
- return modify_route_inet(file, lineno, RTM_DELROUTE, 0, ifname,
+ return modify_route_inet(file, lineno, strict, RTM_DELROUTE, 0, ifname,
srcaddr, srcprefix, dstaddr, dstprefix, gateway);
}
+
+static int modify_qdisc(const char *file, const int lineno, int strict,
+ const char *object, unsigned int action, unsigned int nl_flags,
+ const char *ifname, unsigned int family, unsigned int parent,
+ unsigned int handle, unsigned int info, const char *qd_kind,
+ const struct tst_rtnl_attr_list *config)
+{
+ struct tst_rtnl_context *ctx;
+ int ret;
+ struct tcmsg msg = {
+ .tcm_family = family,
+ .tcm_handle = handle,
+ .tcm_parent = parent,
+ .tcm_info = info
+ };
+
+ if (!qd_kind) {
+ tst_brk_(file, lineno, TBROK,
+ "Queueing discipline name required");
+ return 0;
+ }
+
+ if (ifname) {
+ msg.tcm_ifindex = tst_netdev_index_by_name(file, lineno,
+ ifname);
+
+ if (msg.tcm_ifindex < 0) {
+ tst_brk_(file, lineno, TBROK, "Interface %s not found",
+ ifname);
+ return 0;
+ }
+ }
+
+ ctx = create_request(file, lineno, action, nl_flags, &msg, sizeof(msg));
+
+ if (!ctx)
+ return 0;
+
+ if (!tst_rtnl_add_attr_string(file, lineno, ctx, TCA_KIND, qd_kind)) {
+ tst_rtnl_destroy_context(file, lineno, ctx);
+ return 0;
+ }
+
+ if (config && !tst_rtnl_add_attr_list(file, lineno, ctx, config)) {
+ tst_rtnl_destroy_context(file, lineno, ctx);
+ return 0;
+ }
+
+ ret = tst_rtnl_send_validate(file, lineno, ctx);
+ tst_rtnl_destroy_context(file, lineno, ctx);
+
+ if (strict && !ret) {
+ tst_brk_(file, lineno, TBROK,
+ "Failed to modify %s: %s", object,
+ tst_strerrno(tst_rtnl_errno));
+ }
+
+ return ret;
+}
+
+int tst_netdev_add_qdisc(const char *file, const int lineno, int strict,
+ const char *ifname, unsigned int family, unsigned int parent,
+ unsigned int handle, const char *qd_kind,
+ const struct tst_rtnl_attr_list *config)
+{
+ return modify_qdisc(file, lineno, strict, "queueing discipline",
+ RTM_NEWQDISC, NLM_F_CREATE | NLM_F_EXCL, ifname, family,
+ parent, handle, 0, qd_kind, config);
+}
+
+int tst_netdev_remove_qdisc(const char *file, const int lineno, int strict,
+ const char *ifname, unsigned int family, unsigned int parent,
+ unsigned int handle, const char *qd_kind)
+{
+ return modify_qdisc(file, lineno, strict, "queueing discipline",
+ RTM_DELQDISC, 0, ifname, family, parent, handle, 0, qd_kind,
+ NULL);
+}
+
+int tst_netdev_add_traffic_class(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, const char *qd_kind,
+ const struct tst_rtnl_attr_list *config)
+{
+ return modify_qdisc(file, lineno, strict, "traffic class",
+ RTM_NEWTCLASS, NLM_F_CREATE | NLM_F_EXCL, ifname, AF_UNSPEC,
+ parent, handle, 0, qd_kind, config);
+}
+
+int tst_netdev_remove_traffic_class(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, const char *qd_kind)
+{
+ return modify_qdisc(file, lineno, strict, "traffic class",
+ RTM_DELTCLASS, 0, ifname, AF_UNSPEC, parent, handle, 0,
+ qd_kind, NULL);
+}
+
+int tst_netdev_add_traffic_filter(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, unsigned int protocol, unsigned int priority,
+ const char *f_kind, const struct tst_rtnl_attr_list *config)
+{
+ return modify_qdisc(file, lineno, strict, "traffic filter",
+ RTM_NEWTFILTER, NLM_F_CREATE | NLM_F_EXCL, ifname, AF_UNSPEC,
+ parent, handle, TC_H_MAKE(priority << 16, htons(protocol)),
+ f_kind, config);
+}
+
+int tst_netdev_remove_traffic_filter(const char *file, const int lineno,
+ int strict, const char *ifname, unsigned int parent,
+ unsigned int handle, unsigned int protocol, unsigned int priority,
+ const char *f_kind)
+{
+ return modify_qdisc(file, lineno, strict, "traffic filter",
+ RTM_DELTFILTER, 0, ifname, AF_UNSPEC, parent, handle,
+ TC_H_MAKE(priority << 16, htons(protocol)), f_kind, NULL);
+}
diff --git a/lib/tst_pid.c b/lib/tst_pid.c
index 21cadef2a..cfaa5db36 100644
--- a/lib/tst_pid.c
+++ b/lib/tst_pid.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
@@ -29,8 +30,10 @@
#include "tst_pid.h"
#include "old_safe_file_ops.h"
#include "tst_safe_macros.h"
+#include "lapi/syscalls.h"
#define PID_MAX_PATH "/proc/sys/kernel/pid_max"
+#define THREADS_MAX_PATH "/proc/sys/kernel/threads-max"
#define CGROUPS_V1_SLICE_FMT "/sys/fs/cgroup/pids/user.slice/user-%d.slice/pids.max"
#define CGROUPS_V2_SLICE_FMT "/sys/fs/cgroup/user.slice/user-%d.slice/pids.max"
/* Leave some available processes for the OS */
@@ -110,25 +113,35 @@ static int get_session_pids_limit(void (*cleanup_fn) (void))
return max_pids;
}
-int tst_get_free_pids_(void (*cleanup_fn) (void))
+static int get_used_pids(void (*cleanup_fn) (void))
{
- FILE *f;
- int rc, used_pids, max_pids, max_session_pids;
-
- f = popen("ps -eT | wc -l", "r");
- if (!f) {
- tst_brkm(TBROK, cleanup_fn, "Could not run 'ps' to calculate used pids");
- return -1;
+ DIR *dir_proc;
+ struct dirent *ent;
+ char status_path[PATH_MAX];
+ int used_threads, used_pids = 0;
+
+ dir_proc = SAFE_OPENDIR("/proc");
+
+ while ((ent = SAFE_READDIR(dir_proc))) {
+ if (isdigit(ent->d_name[0])) {
+ snprintf(status_path, sizeof(status_path), "/proc/%s/status", ent->d_name);
+ if (!FILE_LINES_SCANF(cleanup_fn, status_path, "Threads: %d", &used_threads))
+ used_pids += used_threads;
+ }
}
- rc = fscanf(f, "%i", &used_pids);
- pclose(f);
- if (rc != 1 || used_pids < 0) {
- tst_brkm(TBROK, cleanup_fn, "Could not read output of 'ps' to calculate used pids");
- return -1;
- }
+ SAFE_CLOSEDIR(dir_proc);
+
+ return used_pids;
+}
+
+int tst_get_free_pids_(void (*cleanup_fn) (void))
+{
+ int max_pids, max_session_pids, max_threads, used_pids = get_used_pids(cleanup_fn);
SAFE_FILE_SCANF(cleanup_fn, PID_MAX_PATH, "%d", &max_pids);
+ SAFE_FILE_SCANF(cleanup_fn, THREADS_MAX_PATH, "%d", &max_threads);
+ max_pids = MIN(max_pids, max_threads);
max_session_pids = get_session_pids_limit(cleanup_fn);
if ((max_session_pids > 0) && (max_session_pids < max_pids))
@@ -148,3 +161,8 @@ int tst_get_free_pids_(void (*cleanup_fn) (void))
}
return max_pids - used_pids;
}
+
+pid_t tst_getpid(void)
+{
+ return syscall(SYS_getpid);
+}
diff --git a/lib/tst_test.c b/lib/tst_test.c
index 23d21c825..0dec00be4 100644
--- a/lib/tst_test.c
+++ b/lib/tst_test.c
@@ -34,6 +34,7 @@
#include "old_resource.h"
#include "old_device.h"
#include "old_tmpdir.h"
+#include "ltp-version.h"
/*
* Hack to get TCID defined in newlib tests
@@ -44,6 +45,7 @@ const char *TCID __attribute__((weak));
#define LINUX_GIT_URL "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id="
#define LINUX_STABLE_GIT_URL "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id="
#define GLIBC_GIT_URL "https://sourceware.org/git/?p=glibc.git;a=commit;h="
+#define MUSL_GIT_URL "https://git.musl-libc.org/cgit/musl/commit/src/linux/clone.c?id="
#define CVE_DB_URL "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-"
#define DEFAULT_TIMEOUT 30
@@ -94,7 +96,7 @@ static void setup_ipc(void)
if (access("/dev/shm", F_OK) == 0) {
snprintf(shm_path, sizeof(shm_path), "/dev/shm/ltp_%s_%d",
- tid, getpid());
+ tid, getpid());
} else {
char *tmpdir;
@@ -103,7 +105,7 @@ static void setup_ipc(void)
tmpdir = tst_get_tmpdir();
snprintf(shm_path, sizeof(shm_path), "%s/ltp_%s_%d",
- tmpdir, tid, getpid());
+ tmpdir, tid, getpid());
free(tmpdir);
}
@@ -127,7 +129,7 @@ static void setup_ipc(void)
SAFE_CLOSE(ipc_fd);
if (tst_test->needs_checkpoints) {
- tst_futexes = (char*)results + sizeof(struct results);
+ tst_futexes = (char *)results + sizeof(struct results);
tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t);
}
}
@@ -143,8 +145,8 @@ static void cleanup_ipc(void)
tst_res(TWARN | TERRNO, "unlink(%s) failed", shm_path);
if (results) {
- msync((void*)results, size, MS_SYNC);
- munmap((void*)results, size);
+ msync((void *)results, size, MS_SYNC);
+ munmap((void *)results, size);
results = NULL;
}
}
@@ -164,7 +166,7 @@ void tst_reinit(void)
fd = SAFE_OPEN(path, O_RDWR);
results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- tst_futexes = (char*)results + sizeof(struct results);
+ tst_futexes = (char *)results + sizeof(struct results);
tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t);
SAFE_CLOSE(fd);
@@ -195,7 +197,7 @@ static void update_results(int ttype)
}
static void print_result(const char *file, const int lineno, int ttype,
- const char *fmt, va_list va)
+ const char *fmt, va_list va)
{
char buf[1024];
char *str = buf;
@@ -286,16 +288,16 @@ static void print_result(const char *file, const int lineno, int ttype,
}
}
-void tst_vres_(const char *file, const int lineno, int ttype,
- const char *fmt, va_list va)
+void tst_vres_(const char *file, const int lineno, int ttype, const char *fmt,
+ va_list va)
{
print_result(file, lineno, ttype, fmt, va);
update_results(TTYPE_RESULT(ttype));
}
-void tst_vbrk_(const char *file, const int lineno, int ttype,
- const char *fmt, va_list va);
+void tst_vbrk_(const char *file, const int lineno, int ttype, const char *fmt,
+ va_list va);
static void (*tst_brk_handler)(const char *file, const int lineno, int ttype,
const char *fmt, va_list va) = tst_vbrk_;
@@ -324,8 +326,8 @@ static void do_test_cleanup(void)
tst_brk_handler = tst_vbrk_;
}
-void tst_vbrk_(const char *file, const int lineno, int ttype,
- const char *fmt, va_list va)
+void tst_vbrk_(const char *file, const int lineno, int ttype, const char *fmt,
+ va_list va)
{
print_result(file, lineno, ttype, fmt, va);
update_results(TTYPE_RESULT(ttype));
@@ -336,7 +338,7 @@ void tst_vbrk_(const char *file, const int lineno, int ttype,
* specified but CLONE_THREAD is not. Use direct syscall to avoid
* cleanup running in the child.
*/
- if (syscall(SYS_getpid) == main_pid)
+ if (tst_getpid() == main_pid)
do_test_cleanup();
if (getpid() == lib_pid)
@@ -346,7 +348,7 @@ void tst_vbrk_(const char *file, const int lineno, int ttype,
}
void tst_res_(const char *file, const int lineno, int ttype,
- const char *fmt, ...)
+ const char *fmt, ...)
{
va_list va;
@@ -356,7 +358,7 @@ void tst_res_(const char *file, const int lineno, int ttype,
}
void tst_brk_(const char *file, const int lineno, int ttype,
- const char *fmt, ...)
+ const char *fmt, ...)
{
va_list va;
@@ -379,8 +381,8 @@ static void check_child_status(pid_t pid, int status)
int ret;
if (WIFSIGNALED(status)) {
- tst_brk(TBROK, "Child (%i) killed by signal %s",
- pid, tst_strsig(WTERMSIG(status)));
+ tst_brk(TBROK, "Child (%i) killed by signal %s", pid,
+ tst_strsig(WTERMSIG(status)));
}
if (!(WIFEXITED(status)))
@@ -509,6 +511,7 @@ static struct option {
{"h", "-h Prints this help"},
{"i:", "-i n Execute test n times"},
{"I:", "-I x Execute test for n seconds"},
+ {"V", "-V Prints LTP version"},
{"C:", "-C ARG Run child process with ARG arguments (used internally)"},
};
@@ -590,6 +593,8 @@ static void print_test_tags(void)
fprintf(stderr, LINUX_STABLE_GIT_URL "%s\n", tags[i].value);
else if (!strcmp(tags[i].name, "glibc-git"))
fprintf(stderr, GLIBC_GIT_URL "%s\n", tags[i].value);
+ else if (!strcmp(tags[i].name, "musl-git"))
+ fprintf(stderr, MUSL_GIT_URL "%s\n", tags[i].value);
else
fprintf(stderr, "%s: %s\n", tags[i].name, tags[i].value);
}
@@ -609,7 +614,7 @@ static void check_option_collision(void)
for (j = 0; j < ARRAY_SIZE(options); j++) {
if (toptions[i].optstr[0] == options[j].optstr[0]) {
tst_brk(TBROK, "Option collision '%s'",
- options[j].help);
+ options[j].help);
}
}
}
@@ -622,7 +627,8 @@ static unsigned int count_options(void)
if (!tst_test->options)
return 0;
- for (i = 0; tst_test->options[i].optstr; i++);
+ for (i = 0; tst_test->options[i].optstr; i++)
+ ;
return i;
}
@@ -678,7 +684,7 @@ static void parse_opts(int argc, char *argv[])
print_test_tags();
exit(0);
case 'i':
- iterations = SAFE_STRTOL(optarg, 1, INT_MAX);
+ iterations = SAFE_STRTOL(optarg, 0, INT_MAX);
break;
case 'I':
if (tst_test->max_runtime > 0)
@@ -686,6 +692,10 @@ static void parse_opts(int argc, char *argv[])
else
duration = SAFE_STRTOF(optarg, 0.1, HUGE_VALF);
break;
+ case 'V':
+ fprintf(stderr, "LTP version: " LTP_VERSION "\n");
+ exit(0);
+ break;
case 'C':
#ifdef UCLINUX
child_args = optarg;
@@ -848,6 +858,7 @@ static void print_failure_hints(void)
print_failure_hint("linux-stable-git", "missing stable kernel fixes",
LINUX_STABLE_GIT_URL);
print_failure_hint("glibc-git", "missing glibc fixes", GLIBC_GIT_URL);
+ print_failure_hint("musl-git", "missing musl fixes", MUSL_GIT_URL);
print_failure_hint("CVE", "vulnerable to CVE(s)", CVE_DB_URL);
print_failure_hint("known-fail", "hit by known kernel failures", NULL);
}
@@ -869,8 +880,10 @@ static void do_exit(int ret)
if (results->warnings)
ret |= TWARN;
- if (results->broken)
+ if (results->broken) {
ret |= TBROK;
+ print_failure_hints();
+ }
fprintf(stderr, "\nSummary:\n");
fprintf(stderr, "passed %d\n", results->passed);
@@ -891,13 +904,13 @@ void check_kver(void)
if (tst_parse_kver(tst_test->min_kver, &v1, &v2, &v3)) {
tst_res(TWARN,
- "Invalid kernel version %s, expected %%d.%%d.%%d",
- tst_test->min_kver);
+ "Invalid kernel version %s, expected %%d.%%d.%%d",
+ tst_test->min_kver);
}
if (tst_kvercmp(v1, v2, v3) < 0) {
tst_brk(TCONF, "The test requires kernel %s or newer",
- tst_test->min_kver);
+ tst_test->min_kver);
}
}
@@ -980,9 +993,8 @@ static void assert_test_fn(void)
tst_brk(TBROK, "You can define tcnt only for test()");
}
-static int prepare_and_mount_ro_fs(const char *dev,
- const char *mntpoint,
- const char *fs_type)
+static int prepare_and_mount_ro_fs(const char *dev, const char *mntpoint,
+ const char *fs_type)
{
char buf[PATH_MAX];
@@ -1078,10 +1090,10 @@ static const char *limit_tmpfs_mount_size(const char *mnt_data,
static const char *get_device_name(const char *fs_type)
{
- if (!strcmp(fs_type, "tmpfs"))
- return "ltp-tmpfs";
- else
- return tdev.dev;
+ if (!strcmp(fs_type, "tmpfs"))
+ return "ltp-tmpfs";
+ else
+ return tdev.dev;
}
static void prepare_device(void)
@@ -1096,7 +1108,7 @@ static void prepare_device(void)
if (tst_test->needs_rofs) {
prepare_and_mount_ro_fs(tdev.dev, tst_test->mntpoint,
- tdev.fs_type);
+ tdev.fs_type);
return;
}
@@ -1157,9 +1169,12 @@ static void do_setup(int argc, char *argv[])
if (tst_test->supported_archs && !tst_is_on_arch(tst_test->supported_archs))
tst_brk(TCONF, "This arch '%s' is not supported for test!", tst_arch.name);
- if (tst_test->skip_in_lockdown && tst_lockdown_enabled())
+ if (tst_test->skip_in_lockdown && tst_lockdown_enabled() > 0)
tst_brk(TCONF, "Kernel is locked down, skipping test");
+ if (tst_test->skip_in_secureboot && tst_secureboot_enabled() > 0)
+ tst_brk(TCONF, "SecureBoot enabled, skipping test");
+
if (tst_test->skip_in_compat && TST_ABI != tst_kernel_bits())
tst_brk(TCONF, "Not supported in 32-bit compat mode");
@@ -1195,6 +1210,9 @@ static void do_setup(int argc, char *argv[])
if (tst_test->min_mem_avail > (unsigned long)(tst_available_mem() / 1024))
tst_brk(TCONF, "Test needs at least %luMB MemAvailable", tst_test->min_mem_avail);
+ if (tst_test->min_swap_avail > (unsigned long)(tst_available_swap() / 1024))
+ tst_brk(TCONF, "Test needs at least %luMB SwapFree", tst_test->min_swap_avail);
+
if (tst_test->hugepages.number)
tst_reserve_hugepages(&tst_test->hugepages);
@@ -1240,7 +1258,7 @@ static void do_setup(int argc, char *argv[])
*/
if (prepare_and_mount_ro_fs(NULL, tst_test->mntpoint, "tmpfs")) {
tst_res(TINFO, "Can't mount tmpfs read-only, "
- "falling back to block device...");
+ "falling back to block device...");
tst_test->needs_device = 1;
tst_test->format_device = 1;
}
@@ -1268,12 +1286,12 @@ static void do_setup(int argc, char *argv[])
prepare_device();
}
- if (tst_test->needs_overlay && !tst_test->mount_device) {
+ if (tst_test->needs_overlay && !tst_test->mount_device)
tst_brk(TBROK, "tst_test->mount_device must be set");
- }
- if (tst_test->needs_overlay && !mntpoint_mounted) {
+
+ if (tst_test->needs_overlay && !mntpoint_mounted)
tst_brk(TBROK, "tst_test->mntpoint must be mounted");
- }
+
if (tst_test->needs_overlay && !ovl_mounted) {
SAFE_MOUNT_OVERLAY();
ovl_mounted = 1;
@@ -1316,7 +1334,7 @@ static void do_test_setup(void)
if (tst_test->setup)
tst_test->setup();
- if (main_pid != getpid())
+ if (main_pid != tst_getpid())
tst_brk(TBROK, "Runaway child in setup()!");
if (tst_test->caps)
@@ -1379,9 +1397,8 @@ static void run_tests(void)
heartbeat();
tst_test->test_all();
- if (getpid() != main_pid) {
+ if (tst_getpid() != main_pid)
exit(0);
- }
tst_reap_children();
@@ -1395,9 +1412,8 @@ static void run_tests(void)
heartbeat();
tst_test->test(i);
- if (getpid() != main_pid) {
+ if (tst_getpid() != main_pid)
exit(0);
- }
tst_reap_children();
@@ -1671,6 +1687,8 @@ void tst_run_tcases(int argc, char *argv[], struct tst_test *self)
SAFE_SIGNAL(SIGALRM, alarm_handler);
SAFE_SIGNAL(SIGUSR1, heartbeat_handler);
+ tst_res(TINFO, "LTP version: "LTP_VERSION);
+
if (tst_test->max_runtime)
results->max_runtime = multiply_runtime(tst_test->max_runtime);
diff --git a/lib/tst_timer_test.c b/lib/tst_timer_test.c
index eaafc6f0f..5a6f957e4 100644
--- a/lib/tst_timer_test.c
+++ b/lib/tst_timer_test.c
@@ -244,7 +244,7 @@ static void write_to_file(void)
* What we do here is:
*
* * Take nsamples measurements of the timer function, the function
- * to be sampled is defined in the the actual test.
+ * to be sampled is defined in the actual test.
*
* * We sort the array of samples, then:
*
diff --git a/libs/libltpnuma/tst_numa.c b/libs/libltpnuma/tst_numa.c
index ef4c8e879..c3297013b 100644
--- a/libs/libltpnuma/tst_numa.c
+++ b/libs/libltpnuma/tst_numa.c
@@ -127,8 +127,8 @@ static int node_has_enough_memory(int node, size_t min_kb)
{
char path[1024];
char buf[1024];
- long mem_total = 0;
- long mem_used = 0;
+ long mem_total = -1;
+ long mem_used = -1;
long file_pages = 0;
long mem_avail;
@@ -161,7 +161,7 @@ static int node_has_enough_memory(int node, size_t min_kb)
fclose(fp);
- if (!mem_total || !mem_used) {
+ if (mem_total == -1 || mem_used == -1) {
tst_res(TWARN, "Failed to parse '%s'", path);
return 0;
}
diff --git a/metadata/parse.sh b/metadata/parse.sh
index 1811665bf..69bf5db65 100755
--- a/metadata/parse.sh
+++ b/metadata/parse.sh
@@ -23,7 +23,7 @@ echo ' "scm_url_base": "https://github.com/linux-test-project/ltp/tree/master/"
echo " \"version\": \"$version\""
echo ' },'
echo ' "defaults": {'
-echo ' "timeout": 300'
+echo ' "timeout": 30'
echo ' },'
echo ' "tests": {'
diff --git a/runtest/containers b/runtest/containers
index 2637b62fe..5dcceab35 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -16,13 +16,15 @@ pidns31 pidns31
pidns32 pidns32
mqns_01 mqns_01
-mqns_01_clone mqns_01 -clone
+mqns_01_clone mqns_01 -m clone
+mqns_01_unshare mqns_01 -m unshare
mqns_02 mqns_02
-mqns_02_clone mqns_02 -clone
-mqns_03 mqns_03
-mqns_03_clone mqns_03 -clone
-mqns_04 mqns_04
-mqns_04_clone mqns_04 -clone
+mqns_02_clone mqns_02 -m clone
+mqns_02_unshare mqns_02 -m unshare
+mqns_03_unshare mqns_03 -m unshare
+mqns_03_clone mqns_03 -m clone
+mqns_04_unshare mqns_04 -m unshare
+mqns_04_clone mqns_04 -m clone
netns_netlink netns_netlink
netns_breakns_ip_ipv4_netlink netns_breakns.sh
@@ -62,16 +64,12 @@ semtest_2ns_clone semtest_2ns -m clone
semtest_2ns_unshare semtest_2ns -m unshare
sem_comm sem_comm
-utstest_unshare_1 utstest unshare 1
-utstest_unshare_2 utstest unshare 2
-utstest_unshare_3 utstest unshare 3
-utstest_unshare_4 utstest unshare 4
-utstest_unshare_5 utstest unshare 5
-utstest_clone_1 utstest clone 1
-utstest_clone_2 utstest clone 2
-utstest_clone_3 utstest clone 3
-utstest_clone_4 utstest clone 4
-utstest_clone_5 utstest clone 5
+utsname01 utsname01
+utsname02 utsname02
+utsname03_clone utsname03 -m clone
+utsname03_unshare utsname03 -m unshare
+utsname04_clone utsname04 -m clone
+utsname04_unshare utsname04 -m unshare
mountns01 mountns01
mountns02 mountns02
diff --git a/runtest/controllers b/runtest/controllers
index 8d1b936bf..93c52c439 100644
--- a/runtest/controllers
+++ b/runtest/controllers
@@ -1,6 +1,7 @@
#DESCRIPTION:Resource Management testing
cgroup_core01 cgroup_core01
cgroup_core02 cgroup_core02
+cgroup_core03 cgroup_core03
cgroup cgroup_regression_test.sh
memcg_regression memcg_regression_test.sh
memcg_test_3 memcg_test_3
diff --git a/runtest/cve b/runtest/cve
index 1ba63c2a7..f9b36a182 100644
--- a/runtest/cve
+++ b/runtest/cve
@@ -5,9 +5,9 @@ cve-2011-2496 vma03
cve-2012-0957 uname04
cve-2014-0196 cve-2014-0196
cve-2015-0235 gethostbyname_r01
+cve-2015-3290 cve-2015-3290
cve-2015-7550 keyctl02
cve-2016-4470 keyctl01.sh
-cve-2015-3290 cve-2015-3290
cve-2016-4997 setsockopt03
cve-2016-5195 dirtyc0w
cve-2016-7042 cve-2016-7042
@@ -19,10 +19,12 @@ cve-2016-10044 cve-2016-10044
cve-2017-2618 cve-2017-2618
cve-2017-2636 pty05
cve-2017-2671 cve-2017-2671
+cve-2017-5754 meltdown
cve-2017-6951 request_key05
cve-2017-7308 setsockopt02
cve-2017-7472 keyctl04
cve-2017-7616 set_mempolicy05
+cve-2017-8890 accept02
cve-2017-10661 timerfd_settime02
cve-2017-12192 keyctl07
cve-2017-12193 add_key04
@@ -31,49 +33,59 @@ cve-2017-15299 request_key03 -b cve-2017-15299
cve-2017-15537 ptrace07
cve-2017-15649 fanout01
cve-2017-15951 request_key03 -b cve-2017-15951
+cve-2017-16939 cve-2017-16939
+cve-2017-16995 bpf_prog03
+cve-2017-17052 cve-2017-17052
+cve-2017-17053 cve-2017-17053
cve-2017-17712 sendmsg03
cve-2017-17805 af_alg02
cve-2017-17806 af_alg01
cve-2017-17807 request_key04
-cve-2017-1000364 stack_clash
-cve-2017-5754 meltdown
-cve-2017-17052 cve-2017-17052
-cve-2017-16939 cve-2017-16939
-cve-2017-16995 bpf_prog03
-cve-2017-17053 cve-2017-17053
cve-2017-18075 pcrypt_aead01
+cve-2017-18344 timer_create03
cve-2017-1000111 setsockopt07
cve-2017-1000112 setsockopt05
+cve-2017-1000364 stack_clash
cve-2017-1000380 snd_timer01
cve-2017-1000405 thp04
cve-2018-5803 sctp_big_chunk
+cve-2018-6927 futex_cmp_requeue02
cve-2018-7566 snd_seq01
cve-2018-8897 ptrace09
cve-2018-9568 connect02
cve-2018-10124 kill13
-cve-2018-1000001 realpath01
-cve-2018-1000199 ptrace08
-cve-2018-1000204 ioctl_sg01
+cve-2018-11508 adjtimex03
cve-2018-12896 timer_settime03
cve-2018-13405 creat09
cve-2018-18445 bpf_prog04
cve-2018-18559 bind06
cve-2018-18955 userns08
cve-2018-19854 crypto_user01
+cve-2018-1000001 realpath01
+cve-2018-1000199 ptrace08
+cve-2018-1000204 ioctl_sg01
cve-2019-8912 af_alg07
cve-2020-11494 pty04
cve-2020-14386 sendto03
cve-2020-14416 pty03
cve-2020-25705 icmp_rate_limit01
cve-2020-29373 io_uring02
+cve-2020-36557 pty06
cve-2021-3444 bpf_prog05
cve-2021-3609 can_bcm01
cve-2021-4034 execve06
+cve-2021-4197_1 cgroup_core01
+cve-2021-4197_2 cgroup_core02
+cve-2021-4204 bpf_prog06
cve-2021-22555 setsockopt08 -i 100
cve-2021-26708 vsock01
cve-2021-22600 setsockopt09
+cve-2021-38604 mq_notify03
cve-2022-0847 dirtypipe
cve-2022-2590 dirtyc0w_shmem
+cve-2022-23222 bpf_prog07
+cve-2023-1829 tcindex01
# Tests below may cause kernel memory leak
cve-2020-25704 perf_event_open03
+cve-2022-0185 fsconfig03
cve-2022-4378 cve-2022-4378
diff --git a/runtest/hugetlb b/runtest/hugetlb
index 9dabeaa39..299c07ac9 100644
--- a/runtest/hugetlb
+++ b/runtest/hugetlb
@@ -34,6 +34,7 @@ hugemmap28 hugemmap28
hugemmap29 hugemmap29
hugemmap30 hugemmap30
hugemmap31 hugemmap31
+hugemmap32 hugemmap32
hugemmap05_1 hugemmap05 -m
hugemmap05_2 hugemmap05 -s
hugemmap05_3 hugemmap05 -s -m
diff --git a/runtest/ipc b/runtest/ipc
index a2135ed80..db7f7bed5 100644
--- a/runtest/ipc
+++ b/runtest/ipc
@@ -28,5 +28,3 @@ pipeio_8 pipeio -T pipeio_8 -c 5 -s 5000 -i 10 -u -f x80
# spawns 5 children to write 10 chunks of 5000 bytes to an unnamed pipe
# using non-blocking I/O
-sem01 sem01
-sem02 sem02
diff --git a/runtest/kvm b/runtest/kvm
index 16e7c07ff..4094a21a8 100644
--- a/runtest/kvm
+++ b/runtest/kvm
@@ -1 +1,4 @@
kvm_pagefault01 kvm_pagefault01
+kvm_svm01 kvm_svm01
+kvm_svm02 kvm_svm02
+kvm_svm03 kvm_svm03
diff --git a/runtest/net.nfs b/runtest/net.nfs
index 3249c35cb..15a960017 100644
--- a/runtest/net.nfs
+++ b/runtest/net.nfs
@@ -58,7 +58,7 @@ nfs41_ipv6_05 nfs05.sh -6 -v 4.1 -t tcp
nfs42_ipv6_05 nfs05.sh -6 -v 4.2 -t tcp
nfs01_06 nfs06.sh -v "3,3,3,4,4,4" -t "udp,udp,tcp,tcp,tcp,tcp"
-nfs02_06 nfs06.sh -v "3,4,4.1,4.2,4.2,4.2" -t "udp,tcp,tcp,tcp,tcp,tcp"
+nfs02_06 nfs06.sh -v "3,4,4.1,4.2,4.2,4.2" -t "tcp,tcp,tcp,tcp,tcp,tcp"
nfs03_ipv6_06 nfs06.sh -6 -v "4,4.1,4.1,4.2,4.2,4.2" -t "tcp,tcp,tcp,tcp,tcp,tcp"
nfs3_07 nfs07.sh -v 3 -t udp
@@ -72,6 +72,17 @@ nfs4_ipv6_07 nfs07.sh -6 -v 4 -t tcp
nfs41_ipv6_07 nfs07.sh -6 -v 4.1 -t tcp
nfs42_ipv6_07 nfs07.sh -6 -v 4.2 -t tcp
+nfs3_08 nfs08.sh -v 3 -t udp
+nfs3t_08 nfs08.sh -v 3 -t tcp
+nfs4_08 nfs08.sh -v 4 -t tcp
+nfs41_08 nfs08.sh -v 4.1 -t tcp
+nfs42_08 nfs08.sh -v 4.2 -t tcp
+nfs3_ipv6_08 nfs08.sh -6 -v 3 -t udp
+nfs3t_ipv6_08 nfs08.sh -6 -v 3 -t tcp
+nfs4_ipv6_08 nfs08.sh -6 -v 4 -t tcp
+nfs41_ipv6_08 nfs08.sh -6 -v 4.1 -t tcp
+nfs42_ipv6_08 nfs08.sh -6 -v 4.2 -t tcp
+
nfslock3_01 nfslock01.sh -v 3 -t udp
nfslock3t_01 nfslock01.sh -v 3 -t tcp
nfslock4_01 nfslock01.sh -v 4 -t tcp
diff --git a/runtest/sched b/runtest/sched
index 592898723..172fe4174 100644
--- a/runtest/sched
+++ b/runtest/sched
@@ -9,6 +9,7 @@ trace_sched01 trace_sched -c 1
cfs_bandwidth01 cfs_bandwidth01 -i 5
hackbench01 hackbench 50 process 1000
hackbench02 hackbench 20 thread 1000
+starvation starvation
sched_cli_serv run_sched_cliserv.sh
# Run this stress test for 2 minutes
diff --git a/runtest/staging b/runtest/staging
index 88dcea79b..ef1cdea15 100644
--- a/runtest/staging
+++ b/runtest/staging
@@ -1,2 +1 @@
# Tests for features that are not yet in the stable kernel ABI
-fanotify23 fanotify23
diff --git a/runtest/syscalls b/runtest/syscalls
index b35a71d03..906753578 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -117,6 +117,7 @@ clone09 clone09
clone301 clone301
clone302 clone302
+clone303 clone303
close01 close01
close02 close02
@@ -175,6 +176,9 @@ epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
epoll_wait03 epoll_wait03
epoll_wait04 epoll_wait04
+epoll_wait05 epoll_wait05
+epoll_wait06 epoll_wait06
+epoll_wait07 epoll_wait07
epoll_pwait01 epoll_pwait01
epoll_pwait02 epoll_pwait02
epoll_pwait03 epoll_pwait03
@@ -182,6 +186,11 @@ epoll_pwait04 epoll_pwait04
epoll_pwait05 epoll_pwait05
eventfd01 eventfd01
+eventfd02 eventfd02
+eventfd03 eventfd03
+eventfd04 eventfd04
+eventfd05 eventfd05
+eventfd06 eventfd06
eventfd2_01 eventfd2_01
eventfd2_02 eventfd2_02
@@ -210,6 +219,11 @@ exit_group01 exit_group01
#faccessat test cases
faccessat01 faccessat01
+faccessat02 faccessat02
+
+#faccessat2 test cases
+faccessat201 faccessat201
+faccessat202 faccessat202
#fallocate test cases
fallocate01 fallocate01
@@ -271,8 +285,6 @@ fcntl04 fcntl04
fcntl04_64 fcntl04_64
fcntl05 fcntl05
fcntl05_64 fcntl05_64
-fcntl06 fcntl06
-fcntl06_64 fcntl06_64
fcntl07 fcntl07
fcntl07_64 fcntl07_64
fcntl08 fcntl08
@@ -383,6 +395,7 @@ fremovexattr02 fremovexattr02
fsconfig01 fsconfig01
fsconfig02 fsconfig02
+fsconfig03 fsconfig03
fsmount01 fsmount01
fsmount02 fsmount02
@@ -544,11 +557,11 @@ init_module01 init_module01
init_module02 init_module02
#Needs tty device.
-#ioctl01 ioctl01 -D /dev/tty0
#ioctl02 ioctl02 -D /dev/tty0
# Introducing ioctl tests for all /dev/tty* devices
-ioctl01_02 test_ioctl
+ioctl01 ioctl01
+ioctl02 test_ioctl
ioctl03 ioctl03
ioctl04 ioctl04
ioctl05 ioctl05
@@ -613,6 +626,7 @@ fanotify19 fanotify19
fanotify20 fanotify20
fanotify21 fanotify21
fanotify22 fanotify22
+fanotify23 fanotify23
ioperm01 ioperm01
ioperm02 ioperm02
@@ -780,7 +794,6 @@ mmap03 mmap03
mmap04 mmap04
mmap05 mmap05
mmap06 mmap06
-mmap07 mmap07
mmap08 mmap08
mmap09 mmap09
mmap12 mmap12
@@ -793,6 +806,7 @@ mmap16 mmap16
mmap17 mmap17
mmap18 mmap18
mmap19 mmap19
+mmap20 mmap20
modify_ldt01 modify_ldt01
modify_ldt02 modify_ldt02
@@ -804,6 +818,7 @@ mount03 mount03
mount04 mount04
mount05 mount05
mount06 mount06
+mount07 mount07
mount_setattr01 mount_setattr01
@@ -826,11 +841,13 @@ mprotect01 mprotect01
mprotect02 mprotect02
mprotect03 mprotect03
mprotect04 mprotect04
+mprotect05 mprotect05
pkey01 pkey01
mq_notify01 mq_notify01
mq_notify02 mq_notify02
+mq_notify03 mq_notify03
mq_open01 mq_open01
mq_timedreceive01 mq_timedreceive01
mq_timedsend01 mq_timedsend01
@@ -841,6 +858,7 @@ mremap02 mremap02
mremap03 mremap03
mremap04 mremap04
mremap05 mremap05
+mremap06 mremap06
msgctl01 msgctl01
msgctl02 msgctl02
@@ -947,6 +965,7 @@ madvise07 madvise07
madvise08 madvise08
madvise09 madvise09
madvise10 madvise10
+madvise11 madvise11
newuname01 newuname01
@@ -984,6 +1003,7 @@ pipe10 pipe10
pipe11 pipe11
pipe12 pipe12
pipe13 pipe13
+pipe14 pipe14
pipe2_01 pipe2_01
pipe2_02 pipe2_02
@@ -1034,6 +1054,8 @@ process_vm_readv03 process_vm_readv03
process_vm_writev01 process_vm01
process_vm_writev02 process_vm_writev02
+process_madvise01 process_madvise01
+
prot_hsymlinks prot_hsymlinks
dirtyc0w dirtyc0w
dirtyc0w_shmem dirtyc0w_shmem
@@ -1245,13 +1267,13 @@ semctl09 semctl09
semget01 semget01
semget02 semget02
-semget03 semget03
semget05 semget05
-semget06 semget06
semop01 semop01
semop02 semop02
semop03 semop03
+semop04 semop04
+semop05 semop05
send01 send01
send02 send02
@@ -1332,8 +1354,6 @@ setgroups02 setgroups02
setgroups02_16 setgroups02_16
setgroups03 setgroups03
setgroups03_16 setgroups03_16
-setgroups04 setgroups04
-setgroups04_16 setgroups04_16
sethostname01 sethostname01
sethostname02 sethostname02
@@ -1776,6 +1796,9 @@ statx06 statx06
statx07 statx07
statx08 statx08
statx09 statx09
+statx10 statx10
+statx11 statx11
+statx12 statx12
membarrier01 membarrier01
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index b758158c3..df41140a7 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -41,9 +41,7 @@ semctl09 semctl09
semget01 semget01
semget02 semget02
-semget03 semget03
semget05 semget05
-semget06 semget06
semop01 semop01
semop02 semop02
diff --git a/testcases/commands/df/df01.sh b/testcases/commands/df/df01.sh
index ae0449c3c..5af4f68e6 100755
--- a/testcases/commands/df/df01.sh
+++ b/testcases/commands/df/df01.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2015 Fujitsu Ltd.
-# Copyright (c) 2018-2022 Petr Vorel <pvorel@suse.cz>
+# Copyright (c) 2018-2023 Petr Vorel <pvorel@suse.cz>
# Author: Zhang Jin <jy_zhangjin@cn.fujitsu.com>
#
# Test df command with some basic options.
@@ -46,6 +46,11 @@ df_test()
ROD_SILENT rm -rf $TST_MNTPOINT/testimg
+ # force all the background garbage collection to run to completion
+ if [ "$TST_FS_TYPE" = "xfs" ]; then
+ tst_fsfreeze $TST_MNTPOINT
+ fi
+
# flush file system buffers, then we can get the actual sizes.
sync
}
diff --git a/testcases/commands/eject/eject-tests.sh b/testcases/commands/eject/eject-tests.sh
index 7b916cfb6..76a667aa3 100755
--- a/testcases/commands/eject/eject-tests.sh
+++ b/testcases/commands/eject/eject-tests.sh
@@ -99,7 +99,7 @@ test3()
if grep -q "$CD_DRIVE" /proc/mounts; then
tst_res TFAIL "$CD_DRIVE is stil moutned"
else
- tst_res TPASS "$CD_DRIVE umounted succesfully"
+ tst_res TPASS "$CD_DRIVE umounted successfully"
fi
}
diff --git a/testcases/commands/file/datafiles/in.csh b/testcases/commands/file/datafiles/in.csh
deleted file mode 100644
index c475aef9c..000000000
--- a/testcases/commands/file/datafiles/in.csh
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/csh
-
-echo "this is a shell script"
-echo "used to test file command"
diff --git a/testcases/commands/file/datafiles/in.ksh b/testcases/commands/file/datafiles/in.ksh
deleted file mode 100644
index 3ae45125c..000000000
--- a/testcases/commands/file/datafiles/in.ksh
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/ksh
-
-echo "this is a shell script"
-echo "used to test file command"
diff --git a/testcases/commands/file/file01.sh b/testcases/commands/file/file01.sh
index df152b656..f0c129f33 100755
--- a/testcases/commands/file/file01.sh
+++ b/testcases/commands/file/file01.sh
@@ -2,12 +2,13 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) International Business Machines Corp., 2001
# Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz>
+# Copyright (c) Linux Test Project, 2017-2023
#
# This program tests the file command. The tests are aimed at
# testing if the file command can recognize some of the commonly
# used file formats like, tar, tar.gz, rpm, C, ASCII, ELF etc.
-TST_CNT=20
+TST_CNT=18
TST_SETUP=setup
TST_TESTFUNC=do_test
TST_NEEDS_TMPDIR=1
@@ -61,30 +62,28 @@ do_test()
"POSIX shell script text executable" \
"POSIX shell script text" \
"Bourne shell script text executable";;
- 4) file_test in.ksh "Korn shell script";;
- 5) file_test in.csh "C shell script";;
- 6) file_test in.c "ASCII C program text" "C source, ASCII text";;
- 7) file_test in.pl "[pP]erl script, ASCII text executable" \
+ 4) file_test in.c "ASCII C program text" "C source, ASCII text";;
+ 5) file_test in.pl "[pP]erl script, ASCII text executable" \
"[pP]erl script text executable" \
"a /usr/bin/perl script text";;
- 8) file_test in.py "[pP]ython3\{0,1\} script, ASCII text executable" \
+ 6) file_test in.py "[pP]ython3\{0,1\} script, ASCII text executable" \
"[pP]ython3\{0,1\} script text executable";;
- 9) file_test in.m4 "M4 macro processor script, ASCII text" \
+ 7) file_test in.m4 "M4 macro processor script, ASCII text" \
"ASCII M4 macro language pre-processor text";;
- 10) file_test in "ELF .*-bit $TEST_ARCH executable, .*" \
+ 8) file_test in "ELF .*-bit $TEST_ARCH executable, .*" \
"ELF .*-bit $TEST_ARCH shared object, .*" \
"ELF .*-bit $TEST_ARCH pie executable, .*" \
"ELF .*-bit $TEST_ARCH pie shared object, .*";;
- 11) file_test in.ar "current ar archive";;
- 12) file_test in.tar "tar archive";;
- 13) file_test in.tar.gz "gzip compressed data, .*";;
- 14) file_test in.tar.bz2 "bzip2 compressed data, .*";;
- 15) file_test in.src.rpm "RPM v3 src" "RPM v3.0 src";;
- 16) file_test in.jpg "JPEG image data";;
- 17) file_test in.png "PNG image data";;
- 18) file_test in.wav "RIFF (little-endian) data, WAVE audio, Microsoft PCM";;
- 19) file_test in.mp3 "MPEG ADTS, layer III";;
- 20) file_test in.zip "Zip archive data";;
+ 9) file_test in.ar "current ar archive";;
+ 10) file_test in.tar "tar archive";;
+ 11) file_test in.tar.gz "gzip compressed data, .*";;
+ 12) file_test in.tar.bz2 "bzip2 compressed data, .*";;
+ 13) file_test in.src.rpm "RPM v3 src" "RPM v3.0 src";;
+ 14) file_test in.jpg "JPEG image data";;
+ 15) file_test in.png "PNG image data";;
+ 16) file_test in.wav "RIFF (little-endian) data, WAVE audio, Microsoft PCM";;
+ 17) file_test in.mp3 "MPEG ADTS, layer III";;
+ 18) file_test in.zip "Zip archive data";;
esac
}
diff --git a/testcases/commands/insmod/insmod01.sh b/testcases/commands/insmod/insmod01.sh
index 1881ba389..992b4a05a 100755
--- a/testcases/commands/insmod/insmod01.sh
+++ b/testcases/commands/insmod/insmod01.sh
@@ -1,6 +1,7 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2016 Fujitsu Ltd.
+# Copyright (c) Linux Test Project, 2016-2023
# Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
#
# Test basic functionality of insmod command.
@@ -10,6 +11,8 @@ TST_TESTFUNC=do_test
TST_NEEDS_ROOT=1
TST_NEEDS_CMDS="rmmod insmod"
TST_NEEDS_MODULE="ltp_insmod01.ko"
+TST_SKIP_IN_LOCKDOWN=1
+TST_SKIP_IN_SECUREBOOT=1
inserted=0
diff --git a/testcases/cve/.gitignore b/testcases/cve/.gitignore
index 90e8b191c..3a2b2bed6 100644
--- a/testcases/cve/.gitignore
+++ b/testcases/cve/.gitignore
@@ -12,3 +12,4 @@ cve-2017-16939
cve-2017-17053
cve-2022-4378
icmp_rate_limit01
+tcindex01
diff --git a/testcases/cve/cve-2015-3290.c b/testcases/cve/cve-2015-3290.c
index f61d2809b..a2a8fcedd 100644
--- a/testcases/cve/cve-2015-3290.c
+++ b/testcases/cve/cve-2015-3290.c
@@ -195,7 +195,8 @@ static void set_ldt(void)
.useable = 0
};
- TEST(tst_syscall(__NR_modify_ldt, 1, &data_desc, sizeof(data_desc)));
+ TEST((int)tst_syscall(__NR_modify_ldt, 1, &data_desc,
+ sizeof(data_desc)));
if (TST_RET == -EINVAL) {
tst_brk(TCONF | TRERRNO,
"modify_ldt: 16-bit data segments are probably disabled");
diff --git a/testcases/cve/cve-2016-10044.c b/testcases/cve/cve-2016-10044.c
index 9ac644fc2..6a8c77f3e 100644
--- a/testcases/cve/cve-2016-10044.c
+++ b/testcases/cve/cve-2016-10044.c
@@ -19,7 +19,7 @@
#include "tst_safe_stdio.h"
#include "lapi/syscalls.h"
-static FILE *f;
+static FILE * f;
static void cleanup(void)
{
@@ -29,7 +29,7 @@ static void cleanup(void)
static void run(void)
{
- void* ctx = 0;
+ void *ctx = 0;
char perms[8], line[BUFSIZ];
SAFE_PERSONALITY(READ_IMPLIES_EXEC);
@@ -44,7 +44,7 @@ static void run(void)
tst_brk(TCONF, "Could not find mapping in /proc/self/maps");
found_mapping:
- if (sscanf(line, "%*x-%*x %s7", perms) < 0)
+ if (sscanf(line, "%*x-%*x %s", perms) != 1)
tst_brk(TBROK, "failed to find permission string in %s", line);
if (strchr(perms, (int)'x'))
tst_res(TFAIL, "AIO mapping is executable: %s!", perms);
diff --git a/testcases/cve/stack_clash.c b/testcases/cve/stack_clash.c
index cd7f148c2..3a99c49bb 100644
--- a/testcases/cve/stack_clash.c
+++ b/testcases/cve/stack_clash.c
@@ -1,9 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Pavel Boldin <pboldin@cloudlinux.com>
+ * Copyright (c) 2023 Rick Edgecombe <rick.p.edgecombe@intel.com>
+ * Copyright (c) Linux Test Project, 2017-2023
*/
-/* This is a regression test of the Stack Clash [1] vulnerability. This tests
+/*\
+ * [Description]
+ *
+ * This is a regression test of the Stack Clash [1] vulnerability. This tests
* that there is at least 256 PAGE_SIZE of stack guard gap which is considered
* hard to hop above. Code adapted from the Novell's bugzilla [2].
*
@@ -18,11 +23,19 @@
* to infinity and preallocate REQ_STACK_SIZE bytes of stack so that no calls
* after `mmap` are moving stack further.
*
+ * If the architecture meets certain requirements (only x86_64 is verified)
+ * then the test also tests that new mmap()s can't be placed in the stack's
+ * guard gap. This part of the test works by forcing a bottom up search. The
+ * assumptions are that the stack grows down (start gap) and either:
+ *
+ * 1. The default search is top down, and will switch to bottom up if
+ * space is exhausted.
+ * 2. The default search is bottom up and the stack is above mmap base.
+ *
* [1] https://blog.qualys.com/securitylabs/2017/06/19/the-stack-clash
* [2] https://bugzilla.novell.com/show_bug.cgi?id=CVE-2017-1000364
*/
-#include <sys/mman.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
@@ -32,6 +45,7 @@
#include "tst_test.h"
#include "tst_safe_stdio.h"
+#include "lapi/mmap.h"
static unsigned long page_size;
static unsigned long page_mask;
@@ -78,6 +92,49 @@ void segv_handler(int sig, siginfo_t *info, void *data LTP_ATTRIBUTE_UNUSED)
_exit(EXIT_SUCCESS);
}
+static void force_bottom_up(void)
+{
+ FILE *fh;
+ char buf[1024];
+ unsigned long start, end, size, lastend = 0;
+
+ /* start filling from mmap_min_addr */
+ SAFE_FILE_SCANF("/proc/sys/vm/mmap_min_addr", "%lu", &lastend);
+
+ fh = SAFE_FOPEN("/proc/self/maps", "r");
+
+ while (!feof(fh)) {
+ if (fgets(buf, sizeof(buf), fh) == NULL)
+ goto out;
+
+ if (sscanf(buf, "%lx-%lx", &start, &end) != 2) {
+ tst_brk(TBROK | TERRNO, "sscanf");
+ goto out;
+ }
+
+ size = start - lastend;
+
+ /* Skip the PROT_NONE that was just added (!size). */
+ if (!size) {
+ lastend = end;
+ continue;
+ }
+
+ /* If the next area is the stack, quit. */
+ if (!!strstr(buf, "[stack]"))
+ break;
+
+ /* This is not cleaned up. */
+ SAFE_MMAP((void *)lastend, size, PROT_NONE,
+ MAP_ANON|MAP_PRIVATE|MAP_FIXED_NOREPLACE, -1, 0);
+
+ lastend = end;
+ }
+
+out:
+ SAFE_FCLOSE(fh);
+}
+
unsigned long read_stack_addr_from_proc(unsigned long *stack_size)
{
FILE *fh;
@@ -130,6 +187,28 @@ void __attribute__((noinline)) preallocate_stack(unsigned long required)
garbage[0] = garbage[required - 1] = '\0';
}
+static void do_mmap_placement_test(unsigned long stack_addr, unsigned long gap)
+{
+ void *map_test_gap;
+
+ force_bottom_up();
+
+ /*
+ * force_bottom_up() used up all the spaces below the stack. The search down
+ * path should fail, and search up might take a look at the guard gap
+ * region. If it avoids it, the allocation will be above the stack. If it
+ * uses it, the allocation will be in the gap and the test should fail.
+ */
+ map_test_gap = SAFE_MMAP(0, MAPPED_LEN,
+ PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
+
+ if (stack_addr - gap <= (unsigned long)map_test_gap &&
+ (unsigned long)map_test_gap <= stack_addr) {
+ tst_res(TFAIL, "New mmap was placed in the guard gap.");
+ SAFE_MUNMAP(map_test_gap, MAPPED_LEN);
+ }
+}
+
void do_child(void)
{
unsigned long stack_addr, stack_size;
@@ -179,6 +258,11 @@ void do_child(void)
dump_proc_self_maps();
#endif
+#ifdef __x86_64__
+ do_mmap_placement_test(stack_addr, gap);
+#endif
+
+ /* Now see if it can grow too close to an adjacent region. */
exhaust_stack_into_sigsegv();
}
@@ -252,6 +336,7 @@ static struct tst_test test = {
.test_all = stack_clash_test,
.tags = (const struct tst_tag[]) {
{"CVE", "2017-1000364"},
+ {"linux-git", "58c5d0d6d522"},
{}
}
};
diff --git a/testcases/cve/tcindex01.c b/testcases/cve/tcindex01.c
new file mode 100644
index 000000000..91bfafb53
--- /dev/null
+++ b/testcases/cve/tcindex01.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC
+ * Author: Marcos Paulo de Souza <mpdesouza@suse.com>
+ * LTP port: Martin Doucha <mdoucha@suse.cz>
+ */
+
+/*\
+ * CVE-2023-1829
+ *
+ * Test for use-after-free after removing tcindex traffic filter with certain
+ * parameters.
+ *
+ * Tcindex filter removed in:
+ *
+ * commit 8c710f75256bb3cf05ac7b1672c82b92c43f3d28
+ * Author: Jamal Hadi Salim <jhs@mojatatu.com>
+ * Date: Tue Feb 14 08:49:14 2023 -0500
+ *
+ * net/sched: Retire tcindex classifier
+ */
+
+#include <linux/netlink.h>
+#include <linux/pkt_sched.h>
+#include <linux/pkt_cls.h>
+#include "tst_test.h"
+#include "tst_rtnetlink.h"
+#include "tst_netdevice.h"
+#include "lapi/sched.h"
+#include "lapi/if_ether.h"
+#include "lapi/rtnetlink.h"
+
+#define DEVNAME "ltp_dummy1"
+
+static const uint32_t qd_handle = TC_H_MAKE(1 << 16, 0);
+static const uint32_t clsid = TC_H_MAKE(1 << 16, 1);
+static const uint32_t shift = 10;
+static const uint16_t mask = 0xffff;
+
+/* rtnetlink payloads */
+static const struct tc_htb_glob qd_opt = {
+ .rate2quantum = 10,
+ .version = 3,
+ .defcls = 30
+};
+static struct tc_htb_opt cls_opt = {};
+
+/* htb qdisc and class options */
+static const struct tst_rtnl_attr_list qd_config[] = {
+ {TCA_OPTIONS, NULL, 0, (const struct tst_rtnl_attr_list[]){
+ {TCA_HTB_INIT, &qd_opt, sizeof(qd_opt), NULL},
+ {0, NULL, -1, NULL}
+ }},
+ {0, NULL, -1, NULL}
+};
+static const struct tst_rtnl_attr_list cls_config[] = {
+ {TCA_OPTIONS, NULL, 0, (const struct tst_rtnl_attr_list[]){
+ {TCA_HTB_PARMS, &cls_opt, sizeof(cls_opt), NULL},
+ {0, NULL, -1, NULL}
+ }},
+ {0, NULL, -1, NULL}
+};
+
+/* tcindex filter options */
+static const struct tst_rtnl_attr_list f_config[] = {
+ {TCA_OPTIONS, NULL, 0, (const struct tst_rtnl_attr_list[]){
+ {TCA_TCINDEX_MASK, &mask, sizeof(mask), NULL},
+ {TCA_TCINDEX_SHIFT, &shift, sizeof(shift), NULL},
+ {TCA_TCINDEX_CLASSID, &clsid, sizeof(clsid), NULL},
+ {0, NULL, -1, NULL}
+ }},
+ {0, NULL, -1, NULL}
+};
+
+static void setup(void)
+{
+ tst_setup_netns();
+ NETDEV_ADD_DEVICE(DEVNAME, "dummy");
+
+ cls_opt.rate.rate = cls_opt.ceil.rate = 256000;
+ cls_opt.buffer = 1000000 * 1600 / cls_opt.rate.rate;
+ cls_opt.cbuffer = 1000000 * 1600 / cls_opt.ceil.rate;
+}
+
+static void run(void)
+{
+ int ret;
+
+ NETDEV_ADD_QDISC(DEVNAME, AF_UNSPEC, TC_H_ROOT, qd_handle, "htb",
+ qd_config);
+ NETDEV_ADD_TRAFFIC_CLASS(DEVNAME, qd_handle, clsid, "htb", cls_config);
+ NETDEV_ADD_TRAFFIC_FILTER(DEVNAME, qd_handle, 10, ETH_P_IP, 1,
+ "tcindex", f_config);
+ NETDEV_REMOVE_TRAFFIC_FILTER(DEVNAME, qd_handle, 10, ETH_P_IP,
+ 1, "tcindex");
+ ret = tst_netdev_add_traffic_filter(__FILE__, __LINE__, 0, DEVNAME,
+ qd_handle, 10, ETH_P_IP, 1, "tcindex", f_config);
+ TST_ERR = tst_rtnl_errno;
+ NETDEV_REMOVE_QDISC(DEVNAME, AF_UNSPEC, TC_H_ROOT, qd_handle, "htb");
+
+ if (ret)
+ tst_res(TPASS, "Removing tcindex filter works correctly");
+ else if (TST_ERR == EEXIST)
+ tst_res(TFAIL, "Kernel traffic filter list is corrupted");
+ else
+ tst_brk(TBROK | TTERRNO, "Unexpected rtnetlink error");
+}
+
+static void cleanup(void)
+{
+ NETDEV_REMOVE_DEVICE(DEVNAME);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .taint_check = TST_TAINT_W | TST_TAINT_D,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_VETH",
+ "CONFIG_USER_NS=y",
+ "CONFIG_NET_NS=y",
+ "CONFIG_NET_SCH_HTB",
+ "CONFIG_NET_CLS_TCINDEX",
+ NULL
+ },
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/user/max_user_namespaces", "1024", TST_SR_SKIP},
+ {}
+ },
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "8c710f75256b"},
+ {"CVE", "2023-1829"},
+ {}
+ }
+};
diff --git a/testcases/kernel/connectors/pec/cn_pec.sh b/testcases/kernel/connectors/pec/cn_pec.sh
index 082e30102..dce7f210b 100755
--- a/testcases/kernel/connectors/pec/cn_pec.sh
+++ b/testcases/kernel/connectors/pec/cn_pec.sh
@@ -11,7 +11,7 @@
TST_OPTS="n:"
TST_SETUP=setup
-TST_TESTFUNC=test
+TST_TESTFUNC=do_test
TST_PARSE_ARGS=parse_args
TST_USAGE=usage
TST_NEEDS_ROOT=1
@@ -66,7 +66,7 @@ setup()
tst_res TINFO "Test process events connector"
}
-test()
+do_test()
{
local event=$2
local gen_pid list_pid gen_rc lis_rc
diff --git a/testcases/kernel/connectors/pec/pec_listener.c b/testcases/kernel/connectors/pec/pec_listener.c
index 21ae53e87..01ee91d43 100644
--- a/testcases/kernel/connectors/pec/pec_listener.c
+++ b/testcases/kernel/connectors/pec/pec_listener.c
@@ -19,9 +19,9 @@
#include <signal.h>
#include <linux/types.h>
#include <linux/netlink.h>
-#include <tst_checkpoint.h>
#define TST_NO_DEFAULT_MAIN
-#include <tst_test.h>
+#include "tst_test.h"
+#include "tst_checkpoint.h"
#ifndef NETLINK_CONNECTOR
diff --git a/testcases/kernel/containers/.gitignore b/testcases/kernel/containers/.gitignore
deleted file mode 100644
index 5c2b90312..000000000
--- a/testcases/kernel/containers/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-/check_for_unshare
-mountns/mountns01
-mountns/mountns02
-mountns/mountns03
-mountns/mountns04
-userns/userns01
-userns/userns02
-userns/userns03
-userns/userns04
-userns/userns05
-userns/userns06_capcheck
-userns/userns06
-userns/userns07
-userns/userns08
diff --git a/testcases/kernel/containers/Makefile b/testcases/kernel/containers/Makefile
index 4285546e7..20d2424a5 100644
--- a/testcases/kernel/containers/Makefile
+++ b/testcases/kernel/containers/Makefile
@@ -1,33 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) International Business Machines Corp., 2007
+# Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
top_srcdir ?= ../../..
include $(top_srcdir)/include/mk/env_pre.mk
-
-LIBDIR := libclone
-
-FILTER_OUT_DIRS := $(LIBDIR)
-
-LIB := $(LIBDIR)/libclone.a
-
-LDLIBS := -ldl -lltp
-
-INSTALL_TARGETS := *.sh
-
-$(LIBDIR):
- mkdir -p "$@"
-
-# Make the target the real lib so we don't have to deal with rebuilding this
-# every time the dependency is evaluated, like with PHONY rules.
-$(LIB): $(LIBDIR)
- $(MAKE) -C $^ -f "$(abs_srcdir)/$(LIBDIR)/Makefile" all
-
-MAKE_DEPS := $(LIB)
-
-trunk-clean:: | lib-clean
-
-lib-clean:: $(LIBDIR)
- $(MAKE) -C $^ -f "$(abs_srcdir)/$(LIBDIR)/Makefile" clean
-
include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/kernel/containers/Makefile.inc b/testcases/kernel/containers/Makefile.inc
deleted file mode 100644
index 179809bc1..000000000
--- a/testcases/kernel/containers/Makefile.inc
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# kernel/containers testcase suite common definitions Makefile.
-#
-# Copyright (C) 2009, Cisco Systems 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Ngie Cooper, July 2009
-#
-
-# DO NOT USE THIS FILE FOR containers / libclone!!!
-
-LIBDIR := ../libclone
-
-LIBS := $(LIBDIR)/libclone.a
-
-CPPFLAGS += -I$(abs_srcdir)/$(LIBDIR)
-
-LDFLAGS += -L$(abs_builddir)/$(LIBDIR)
-
-$(LIBDIR):
- mkdir -p "$@"
-
-# Make the target the real lib so we don't have to deal with rebuilding this
-# every time the dependency is evaluated, like with PHONY rules.
-$(LIBS): $(LIBDIR)
- $(MAKE) -C $^ -f "$(abs_srcdir)/$^/Makefile" all
-
-INSTALL_TARGETS ?= *.sh
-
-MAKE_DEPS := $(LIBS)
-
-# vim: syntax=make
diff --git a/testcases/kernel/containers/README b/testcases/kernel/containers/README
deleted file mode 100644
index c99cacd98..000000000
--- a/testcases/kernel/containers/README
+++ /dev/null
@@ -1,50 +0,0 @@
-################################################################################
-## ##
-## Copyright (c) International Business Machines Corp., 2007 ##
-## ##
-## 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, write to the Free Software ##
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ##
-## ##
-################################################################################
-
-CONTAINER TESTS AUTOMATION SUITE
-----------------------------
-The tests requires the Kernel to be compiled with the following configs
-
-CONFIG_DUMMY=y(or =m)
-CONFIG_NAMESPACES=y
-CONFIG_UTS_NS=y
-CONFIG_IPC_NS=y
-CONFIG_USER_NS=y
-CONFIG_PID_NS=y
-CONFIG_NET_NS=y
-CONFIG_VETH=y(or =m)
-CONFIG_MACVLAN=y(optional)
-
-The container test automation suite helps run the container functionality
-(e.g: utsname etc..) tests and report results. Please refer the following
-each functionality README file for detail:
-
-sysvipc/*
- Contains all the testcases related to IPC NS tests.
-posixmq/*
- Contains all the testcases related to POSIX MQ NS tests. These
- are strictly speaking a part of the ipc namespaces, but can be
- enabled in the kernel without SYSV IPC support.
-utsname/*
- Contains all the testcases related to utsname tests.
-libclone/*
- Contains the library API for clone() .
-netns/*
- Contains the testcases related to the network NS tests.
diff --git a/testcases/kernel/containers/TEST_PLAN.txt b/testcases/kernel/containers/TEST_PLAN.txt
deleted file mode 100644
index 809abaecb..000000000
--- a/testcases/kernel/containers/TEST_PLAN.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-################################################################################
-## Copyright (c) International Business Machines Corp., 2007
-##
-## 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, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-################################################################################
-
-Following are tentative Testcases to be included into LTP-Containers in future:
-
-NAME TENTATIVE-TIME
-=================================================================================
-PID NAMESPACES (NEAR FUTURE)
-NETWORK NAMESPACES (NEAR FUTURE)
-POSIX IPC NAMESPACES (NEAR FUTURE)
-TTY+CONSOLE+DEVPTS NAMESPACES (NEAR FUTURE)
-PROC+SYSFS ISOLATION (NEAR FUTURE)
-PER-CONTAINER CAPABILITY/SECURITY TESTS (NEAR FUTURE)
-=================================================================================
diff --git a/testcases/kernel/containers/libclone/Makefile b/testcases/kernel/containers/libclone/Makefile
deleted file mode 100644
index 13af52b67..000000000
--- a/testcases/kernel/containers/libclone/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-################################################################################
-## ##
-## Copyright (c) International Business Machines Corp., 2007 ##
-## ##
-## 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, write to the Free Software ##
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ##
-## ##
-################################################################################
-
-top_srcdir ?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-INTERNAL_LIB := libclone.a
-
-include $(top_srcdir)/include/mk/lib.mk
diff --git a/testcases/kernel/containers/libclone/libclone.c b/testcases/kernel/containers/libclone/libclone.c
deleted file mode 100644
index db0d9b2a5..000000000
--- a/testcases/kernel/containers/libclone/libclone.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************/
-#include "libclone.h"
-
-int do_clone_tests(unsigned long clone_flags,
- int (*fn1) (void *arg), void *arg1,
- int (*fn2) (void *arg), void *arg2)
-{
- int ret;
-
- ret = ltp_clone_quick(clone_flags | SIGCHLD, fn1, arg1);
-
- if (ret == -1) {
- return -1;
- }
- if (fn2)
- ret = fn2(arg2);
- else
- ret = 0;
-
- return ret;
-}
-
-int do_unshare_tests(unsigned long clone_flags,
- int (*fn1) (void *arg), void *arg1,
- int (*fn2) (void *arg), void *arg2)
-{
- int pid, ret = 0;
- int retpipe[2];
- char buf[2];
-
- if (pipe(retpipe) == -1) {
- perror("pipe");
- return -1;
- }
- pid = fork();
- if (pid == -1) {
- perror("fork");
- close(retpipe[0]);
- close(retpipe[1]);
- return -1;
- }
- if (pid == 0) {
- close(retpipe[0]);
- ret = tst_syscall(SYS_unshare, clone_flags);
- if (ret == -1) {
- if (write(retpipe[1], "0", 2) < 0) {
- perror("unshare:write(retpipe[1], ..)");
- }
- close(retpipe[1]);
- exit(1);
- } else {
- if (write(retpipe[1], "1", 2) < 0) {
- perror("unshare:write(retpipe[1], ..)");
- }
- }
- close(retpipe[1]);
- ret = fn1(arg1);
- exit(ret);
- } else {
- close(retpipe[1]);
- if (read(retpipe[0], &buf, 2) < 0) {
- perror("unshare:read(retpipe[0], ..)");
- }
- close(retpipe[0]);
- if (*buf == '0')
- return -1;
- if (fn2)
- ret = fn2(arg2);
- }
-
- return ret;
-}
-
-int do_plain_tests(int (*fn1) (void *arg), void *arg1,
- int (*fn2) (void *arg), void *arg2)
-{
- int ret = 0, pid;
-
- pid = fork();
- if (pid == -1) {
- perror("fork");
- return -1;
- }
- if (pid == 0)
- exit(fn1(arg1));
- if (fn2)
- ret = fn2(arg2);
- return ret;
-}
-
-int do_clone_unshare_test(int use_clone, unsigned long clone_flags,
- int (*fn1) (void *arg), void *arg1)
-{
- switch (use_clone) {
- case T_NONE:
- return do_plain_tests(fn1, arg1, NULL, NULL);
- case T_CLONE:
- return do_clone_tests(clone_flags, fn1, arg1, NULL, NULL);
- case T_UNSHARE:
- return do_unshare_tests(clone_flags, fn1, arg1, NULL, NULL);
- default:
- printf("%s: bad use_clone option: %d\n", __FUNCTION__,
- use_clone);
- return -1;
- }
-}
-
-/*
- * Run fn1 in a unshared environmnent, and fn2 in the original context
- */
-int do_clone_unshare_tests(int use_clone, unsigned long clone_flags,
- int (*fn1) (void *arg), void *arg1,
- int (*fn2) (void *arg), void *arg2)
-{
- switch (use_clone) {
- case T_NONE:
- return do_plain_tests(fn1, arg1, fn2, arg2);
- case T_CLONE:
- return do_clone_tests(clone_flags, fn1, arg1, fn2, arg2);
- case T_UNSHARE:
- return do_unshare_tests(clone_flags, fn1, arg1, fn2, arg2);
- default:
- printf("%s: bad use_clone option: %d\n", __FUNCTION__,
- use_clone);
- return -1;
- }
-}
diff --git a/testcases/kernel/containers/libclone/libclone.h b/testcases/kernel/containers/libclone/libclone.h
deleted file mode 100644
index e92fdca02..000000000
--- a/testcases/kernel/containers/libclone/libclone.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************/
-#ifndef __LIBCLONE_H
-#define __LIBCLONE_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <libgen.h>
-#include <sys/syscall.h>
-#include <signal.h>
-#include "lapi/syscalls.h"
-#include "test.h"
-#include "lapi/sched.h"
-
-#define T_UNSHARE 0
-#define T_CLONE 1
-#define T_NONE 2
-
-#ifndef SYS_unshare
-#ifdef __NR_unshare
-#define SYS_unshare __NR_unshare
-#elif __i386__
-#define SYS_unshare 310
-#elif __ia64__
-#define SYS_unshare 1296
-#elif __x86_64__
-#define SYS_unshare 272
-#elif __s390x__ || __s390__
-#define SYS_unshare 303
-#elif __powerpc__
-#define SYS_unshare 282
-#else
-#error "unshare not supported on this architecure."
-#endif
-#endif
-
-#ifndef __NR_unshare
-#define __NR_unshare SYS_unshare
-#endif
-
-/*
- * Run fn1 in a unshared environmnent, and fn2 in the original context
- * Fn2 may be NULL.
- */
-
-int do_clone_tests(unsigned long clone_flags,
- int(*fn1)(void *arg), void *arg1,
- int(*fn2)(void *arg), void *arg2);
-
-int do_unshare_tests(unsigned long clone_flags,
- int (*fn1)(void *arg), void *arg1,
- int (*fn2)(void *arg), void *arg2);
-
-int do_fork_tests(int (*fn1)(void *arg), void *arg1,
- int (*fn2)(void *arg), void *arg2);
-
-int do_clone_unshare_test(int use_clone, unsigned long clone_flags,
- int (*fn1)(void *arg), void *arg1);
-
-int do_clone_unshare_tests(int use_clone, unsigned long clone_flags,
- int (*fn1)(void *arg), void *arg1,
- int (*fn2)(void *arg), void *arg2);
-
-#endif
diff --git a/testcases/kernel/containers/mountns/.gitignore b/testcases/kernel/containers/mountns/.gitignore
new file mode 100644
index 000000000..0555e9b3b
--- /dev/null
+++ b/testcases/kernel/containers/mountns/.gitignore
@@ -0,0 +1,4 @@
+mountns01
+mountns02
+mountns03
+mountns04
diff --git a/testcases/kernel/containers/mountns/mountns.h b/testcases/kernel/containers/mountns/mountns.h
index 615f1a058..9bb854659 100644
--- a/testcases/kernel/containers/mountns/mountns.h
+++ b/testcases/kernel/containers/mountns/mountns.h
@@ -8,28 +8,10 @@
#define COMMON_H
#include "tst_test.h"
-#include "lapi/sched.h"
#define DIRA "LTP_DIR_A"
#define DIRB "LTP_DIR_B"
-static int dummy_child(void *v)
-{
- (void)v;
- return 0;
-}
-
-static void check_newns(void)
-{
- int pid, status;
-
- pid = ltp_clone_quick(CLONE_NEWNS | SIGCHLD, dummy_child, NULL);
- if (pid < 0)
- tst_brk(TCONF, "CLONE_NEWNS not supported");
-
- SAFE_WAIT(&status);
-}
-
static void umount_folders(void)
{
if (tst_is_mounted(DIRA))
diff --git a/testcases/kernel/containers/mountns/mountns01.c b/testcases/kernel/containers/mountns/mountns01.c
index e8f176920..8d821ea45 100644
--- a/testcases/kernel/containers/mountns/mountns01.c
+++ b/testcases/kernel/containers/mountns/mountns01.c
@@ -33,8 +33,9 @@
#include <sys/mount.h>
#include "mountns.h"
#include "tst_test.h"
+#include "lapi/sched.h"
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
TST_CHECKPOINT_WAIT(0);
@@ -51,13 +52,14 @@ static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
SAFE_UMOUNT(DIRA);
-
- return 0;
}
static void run(void)
{
- int ret;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWNS,
+ .exit_signal = SIGCHLD,
+ };
SAFE_UNSHARE(CLONE_NEWNS);
@@ -67,9 +69,10 @@ static void run(void)
SAFE_MOUNT(DIRA, DIRA, "none", MS_BIND, NULL);
SAFE_MOUNT("none", DIRA, "none", MS_SHARED, NULL);
- ret = ltp_clone_quick(CLONE_NEWNS | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK, "clone failed");
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
+ }
SAFE_MOUNT(DIRB, DIRA, "none", MS_BIND, NULL);
@@ -93,7 +96,6 @@ static void run(void)
static void setup(void)
{
- check_newns();
create_folders();
}
@@ -107,5 +109,10 @@ static struct tst_test test = {
.cleanup = cleanup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/mountns/mountns02.c b/testcases/kernel/containers/mountns/mountns02.c
index 4b85fa79b..e7a80cbbf 100644
--- a/testcases/kernel/containers/mountns/mountns02.c
+++ b/testcases/kernel/containers/mountns/mountns02.c
@@ -34,8 +34,9 @@
#include <sys/mount.h>
#include "mountns.h"
#include "tst_test.h"
+#include "lapi/sched.h"
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
TST_CHECKPOINT_WAIT(0);
@@ -51,13 +52,14 @@ static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
SAFE_UMOUNT(DIRA);
-
- return 0;
}
static void run(void)
{
- int ret;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWNS,
+ .exit_signal = SIGCHLD,
+ };
SAFE_UNSHARE(CLONE_NEWNS);
@@ -68,9 +70,10 @@ static void run(void)
SAFE_MOUNT("none", DIRA, "none", MS_PRIVATE, NULL);
- ret = ltp_clone_quick(CLONE_NEWNS | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK, "clone failed");
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
+ }
SAFE_MOUNT(DIRB, DIRA, "none", MS_BIND, NULL);
@@ -94,7 +97,6 @@ static void run(void)
static void setup(void)
{
- check_newns();
create_folders();
}
@@ -108,5 +110,10 @@ static struct tst_test test = {
.cleanup = cleanup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/mountns/mountns03.c b/testcases/kernel/containers/mountns/mountns03.c
index 1d26a25d8..6066d1c54 100644
--- a/testcases/kernel/containers/mountns/mountns03.c
+++ b/testcases/kernel/containers/mountns/mountns03.c
@@ -36,8 +36,9 @@
#include <sys/mount.h>
#include "mountns.h"
#include "tst_test.h"
+#include "lapi/sched.h"
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
/*
* makes mount DIRA a slave of DIRA (all slave mounts have
@@ -59,13 +60,14 @@ static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
SAFE_UMOUNT(DIRA);
-
- return 0;
}
static void run(void)
{
- int ret;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWNS,
+ .exit_signal = SIGCHLD,
+ };
SAFE_UNSHARE(CLONE_NEWNS);
@@ -76,9 +78,10 @@ static void run(void)
SAFE_MOUNT("none", DIRA, "none", MS_SHARED, NULL);
- ret = ltp_clone_quick(CLONE_NEWNS | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK, "clone failed");
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
+ }
TST_CHECKPOINT_WAIT(0);
@@ -104,7 +107,6 @@ static void run(void)
static void setup(void)
{
- check_newns();
create_folders();
}
@@ -118,5 +120,10 @@ static struct tst_test test = {
.cleanup = cleanup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/mountns/mountns04.c b/testcases/kernel/containers/mountns/mountns04.c
index fc392f1a7..7b4dcb16d 100644
--- a/testcases/kernel/containers/mountns/mountns04.c
+++ b/testcases/kernel/containers/mountns/mountns04.c
@@ -22,6 +22,7 @@
#include <sys/mount.h>
#include "mountns.h"
#include "tst_test.h"
+#include "lapi/sched.h"
static void run(void)
{
@@ -46,7 +47,6 @@ static void run(void)
static void setup(void)
{
- check_newns();
create_folders();
}
@@ -61,4 +61,8 @@ static struct tst_test test = {
.test_all = run,
.needs_root = 1,
.needs_tmpdir = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/mqns/Makefile b/testcases/kernel/containers/mqns/Makefile
index 64c3763ee..01e90ec33 100644
--- a/testcases/kernel/containers/mqns/Makefile
+++ b/testcases/kernel/containers/mqns/Makefile
@@ -1,29 +1,12 @@
-################################################################################
-## ##
-## Copyright (c) International Business Machines Corp., 2009 ##
-## Copyright (c) Nadia Derbey, 2009 ##
-## ##
-## 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, write to the Free Software ##
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ##
-## ##
-################################################################################
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) International Business Machines Corp., 2009
+# Copyright (c) Nadia Derbey, 2009
+# Copyright (C) 2021 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
-LDLIBS := -lpthread -lrt -lclone $(LDLIBS)
+LDLIBS := -lrt $(LDLIBS)
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/containers/mqns/mqns.h b/testcases/kernel/containers/mqns/mqns.h
deleted file mode 100644
index 5a9056838..000000000
--- a/testcases/kernel/containers/mqns/mqns.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __MQNS_H
-#define __MQNS_H
-
-#define DEV_MQUEUE "/dev/mqueue"
-#define DEV_MQUEUE2 "/dev/mqueue2"
-#define SLASH_MQ1 "/MQ1"
-#define NOSLASH_MQ1 "MQ1"
-#define SLASH_MQ2 "/MQ2"
-#define NOSLASH_MQ2 "MQ2"
-
-#endif /* __MQNS_H */
diff --git a/testcases/kernel/containers/mqns/mqns_01.c b/testcases/kernel/containers/mqns/mqns_01.c
index 1d109e020..d9f6e6c18 100644
--- a/testcases/kernel/containers/mqns/mqns_01.c
+++ b/testcases/kernel/containers/mqns/mqns_01.c
@@ -1,148 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) International Business Machines Corp., 2009
-* Copyright (c) Nadia Derbey, 2009
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Author: Nadia Derbey <Nadia.Derbey@bull.net>
-*
-* Check mqns isolation: father mqns cannot be accessed from newinstance
-*
-* Mount mqueue fs
-* Create a posix mq -->mq1
-* unshare
-* In unshared process:
-* Mount newinstance mqueuefs
-* Check that mq1 is not readable from new ns
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (c) Nadia Derbey, 2009 <Nadia.Derbey@bull.net>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-***************************************************************************/
+/*\
+ * [Description]
+ *
+ * Create a mqueue inside the parent and check if it can be accessed from
+ * the child namespace. Isolated and unshared process can't access to parent,
+ * but plain process can.
+ */
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sys/wait.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "mqns.h"
-#include "mqns_helper.h"
+#include "tst_test.h"
+#include "lapi/sched.h"
+#include "tst_safe_posix_ipc.h"
-char *TCID = "posixmq_namespace_01";
-int TST_TOTAL = 1;
+#define MQNAME "/MQ1"
-int p1[2];
-int p2[2];
+static mqd_t mqd;
+static char *str_op;
-int check_mqueue(void *vtest)
+static void run(void)
{
- char buf[30];
- mqd_t mqd;
+ const struct tst_clone_args clone_args = {
+ .flags = CLONE_NEWIPC,
+ .exit_signal = SIGCHLD,
+ };
- (void) vtest;
+ tst_res(TINFO, "Checking namespaces isolation from parent to child");
- close(p1[1]);
- close(p2[0]);
+ if (str_op && !strcmp(str_op, "clone")) {
+ tst_res(TINFO, "Spawning isolated process");
- if (read(p1[0], buf, strlen("go") + 1) < 0) {
- printf("read(p1[0], ...) failed: %s\n", strerror(errno));
- exit(1);
- }
- mqd = tst_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDONLY);
- if (mqd == -1) {
- if (write(p2[1], "notfnd", strlen("notfnd") + 1) < 0) {
- perror("write(p2[1], ...) failed");
- exit(1);
+ if (!SAFE_CLONE(&clone_args)) {
+ TST_EXP_FAIL(mq_open(MQNAME, O_RDONLY), ENOENT);
+ return;
+ }
+ } else if (str_op && !strcmp(str_op, "unshare")) {
+ tst_res(TINFO, "Spawning unshared process");
+
+ if (!SAFE_FORK()) {
+ SAFE_UNSHARE(CLONE_NEWIPC);
+ TST_EXP_FAIL(mq_open(MQNAME, O_RDONLY), ENOENT);
+ return;
}
} else {
- if (write(p2[1], "exists", strlen("exists") + 1) < 0) {
- perror("write(p2[1], \"exists\", 7) failed");
- exit(1);
- } else if (mq_close(mqd) < 0) {
- perror("mq_close(mqd) failed");
- exit(1);
+ tst_res(TINFO, "Spawning plain process");
+
+ if (!SAFE_FORK()) {
+ TST_EXP_POSITIVE(mq_open(MQNAME, O_RDONLY));
+ return;
}
}
-
- exit(0);
}
static void setup(void)
{
- tst_require_root();
- check_mqns();
+ mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
}
-int main(int argc, char *argv[])
+static void cleanup(void)
{
- int r;
- mqd_t mqd;
- char buf[30];
- int use_clone = T_UNSHARE;
-
- setup();
-
- if (argc == 2 && strcmp(argv[1], "-clone") == 0) {
- tst_resm(TINFO,
- "Testing posix mq namespaces through clone(2).");
- use_clone = T_CLONE;
- } else
- tst_resm(TINFO,
- "Testing posix mq namespaces through unshare(2).");
-
- if (pipe(p1) == -1 || pipe(p2) == -1) {
- tst_brkm(TBROK | TERRNO, NULL, "pipe failed");
- }
-
- mqd = tst_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDWR | O_CREAT | O_EXCL,
- 0777, NULL);
- if (mqd == -1) {
- perror("mq_open");
- tst_brkm(TFAIL, NULL, "mq_open failed");
+ if (mqd != -1) {
+ SAFE_MQ_CLOSE(mqd);
+ SAFE_MQ_UNLINK(MQNAME);
}
-
- tst_resm(TINFO, "Checking namespaces isolation from parent to child");
- /* fire off the test */
- r = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mqueue, NULL);
- if (r < 0) {
- tst_resm(TFAIL, "failed clone/unshare");
- mq_close(mqd);
- tst_syscall(__NR_mq_unlink, NOSLASH_MQ1);
- tst_exit();
- }
-
- close(p1[0]);
- close(p2[1]);
- if (write(p1[1], "go", strlen("go") + 1) < 0)
- tst_resm(TBROK | TERRNO, "write(p1[1], \"go\", ...) failed");
- else if (read(p2[0], buf, 7) < 0)
- tst_resm(TBROK | TERRNO, "read(p2[0], buf, ...) failed");
- else {
- if (!strcmp(buf, "exists")) {
- tst_resm(TFAIL, "child process found mqueue");
- } else if (!strcmp(buf, "notfnd")) {
- tst_resm(TPASS, "child process didn't find mqueue");
- } else {
- tst_resm(TFAIL, "UNKNOWN RESULT");
- }
- }
-
- /* destroy the mqueue */
- if (mq_close(mqd) == -1) {
- tst_brkm(TBROK | TERRNO, NULL, "mq_close failed");
- }
- tst_syscall(__NR_mq_unlink, NOSLASH_MQ1);
-
- tst_exit();
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .forks_child = 1,
+ .options = (struct tst_option[]) {
+ { "m:", &str_op, "Child process isolation <clone|unshare>" },
+ {},
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL
+ },
+};
diff --git a/testcases/kernel/containers/mqns/mqns_02.c b/testcases/kernel/containers/mqns/mqns_02.c
index d4e785b59..4348be7fc 100644
--- a/testcases/kernel/containers/mqns/mqns_02.c
+++ b/testcases/kernel/containers/mqns/mqns_02.c
@@ -1,180 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
/*
-* Copyright (c) International Business Machines Corp., 2009
-* Copyright (c) Nadia Derbey, 2009
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Author: Nadia Derbey <Nadia.Derbey@bull.net>
-*
-* Check mqns isolation: child mqns cannot be accessed from father
-*
-* Mount mqueue fs
-* unshare
-* In unshared process:
-* Mount newinstance mqueuefs
-* Create a posix mq -->mq1
-* Check that mq1 is not readable from father
-*
-* Changelog:
-* Dec 16: accomodate new mqns semantics (Serge Hallyn)
-
-***************************************************************************/
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sys/wait.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "mqns.h"
-#include "mqns_helper.h"
-
-char *TCID = "posixmq_namespace_02";
-int TST_TOTAL = 1;
-
-int p1[2];
-int p2[2];
-
-int check_mqueue(void *vtest)
-{
- char buf[30];
- mqd_t mqd;
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (c) Nadia Derbey, 2009 <Nadia.Derbey@bull.net>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
- (void) vtest;
+/*\
+ * [Description]
+ *
+ * Create a mqueue with the same name in both parent and isolated/forked child,
+ * then check namespace isolation.
+ */
- close(p1[1]);
- close(p2[0]);
+#include "tst_test.h"
+#include "lapi/sched.h"
+#include "tst_safe_posix_ipc.h"
- if (read(p1[0], buf, 3) < 0) {
- perror("read(p1[0], ..) failed");
- exit(1);
- } else {
+#define MQNAME "/MQ1"
- mqd =
- tst_syscall(__NR_mq_open, NOSLASH_MQ1,
- O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
- if (mqd == -1) {
- if (write(p2[1], "mqfail", strlen("mqfail") + 1) < 0) {
- perror("write(p2[1], \"mqfail\", ..) failed");
- exit(1);
- }
- } else {
-
- if (write(p2[1], "mqopen", strlen("mqopen") + 1) < 0) {
- perror("write(p2[1], \"mqopen\", ..) failed");
- exit(1);
- } else {
-
- if (read(p1[0], buf, 5) < 0) {
- perror("read(p1[0], ..) failed");
- exit(1);
- } else {
-
- /* destroy the mqueue */
- if (mq_close(mqd) < 0) {
- perror("mq_close(mqd) failed");
- exit(1);
- } else if (tst_syscall(__NR_mq_unlink,
- NOSLASH_MQ1) < 0) {
- perror("mq_unlink(" NOSLASH_MQ1
- ") failed");
- exit(1);
- } else if (write(p2[1], "done",
- strlen("done") + 1)
- < 0) {
- perror("write(p2[1], "
- "\"done\", ..) failed");
- exit(1);
- }
-
- }
-
- }
+static mqd_t mqd;
+static char *str_op;
- }
+static int create_message_queue(void)
+{
+ return mq_open(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
+}
- }
- exit(0);
+static void shared_child(void)
+{
+ mqd_t mqd1 = -1;
+ TST_EXP_FAIL(mqd1 = create_message_queue(), EEXIST);
+
+ if (mqd1 != -1) {
+ SAFE_MQ_CLOSE(mqd1);
+ SAFE_MQ_UNLINK(MQNAME);
+ }
}
-static void setup(void)
+static void isolated_child(void)
{
- tst_require_root();
- check_mqns();
+ mqd_t mqd1 = -1;
+
+ TST_EXP_POSITIVE(mqd1 = create_message_queue());
+
+ if (mqd1 != -1) {
+ SAFE_MQ_CLOSE(mqd1);
+ SAFE_MQ_UNLINK(MQNAME);
+ }
}
-int main(int argc, char *argv[])
+static void run(void)
{
- int r;
- mqd_t mqd;
- char buf[30];
- int use_clone = T_UNSHARE;
-
- setup();
-
- if (argc == 2 && strcmp(argv[1], "-clone") == 0) {
- tst_resm(TINFO,
- "Testing posix mq namespaces through clone(2).");
- use_clone = T_CLONE;
- } else
- tst_resm(TINFO,
- "Testing posix mq namespaces through unshare(2).");
-
- if (pipe(p1) == -1 || pipe(p2) == -1) {
- tst_brkm(TBROK | TERRNO, NULL, "pipe");
- }
+ const struct tst_clone_args clone_args = {
+ .flags = CLONE_NEWIPC,
+ .exit_signal = SIGCHLD,
+ };
- /* fire off the test */
- r = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mqueue, NULL);
- if (r < 0) {
- tst_brkm(TFAIL, NULL, "failed clone/unshare");
- }
+ tst_res(TINFO, "Checking namespaces isolation from parent to child");
- tst_resm(TINFO, "Checking namespaces isolation (child to parent)");
+ if (str_op && !strcmp(str_op, "clone")) {
+ tst_res(TINFO, "Spawning isolated process");
- close(p1[0]);
- close(p2[1]);
- if (write(p1[1], "go", strlen("go") + 1) < 0) {
- tst_brkm(TBROK, NULL, "write(p1[1], \"go\", ..) failed");
- }
+ if (!SAFE_CLONE(&clone_args)) {
+ isolated_child();
+ return;
+ }
+ } else if (str_op && !strcmp(str_op, "unshare")) {
+ tst_res(TINFO, "Spawning unshared process");
- if (read(p2[0], buf, 7) < 0) {
- tst_resm(TBROK | TERRNO, "read(p2[0], ..) failed");
- } else if (!strcmp(buf, "mqfail")) {
- tst_resm(TFAIL, "child process could not create mqueue");
- umount(DEV_MQUEUE);
- } else if (strcmp(buf, "mqopen")) {
- tst_resm(TFAIL, "child process could not create mqueue");
- umount(DEV_MQUEUE);
- } else {
- mqd = tst_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDONLY);
- if (mqd == -1) {
- tst_resm(TPASS,
- "Parent process can't see the mqueue");
- } else {
- tst_resm(TFAIL | TERRNO,
- "Parent process found mqueue");
- mq_close(mqd);
+ if (!SAFE_FORK()) {
+ SAFE_UNSHARE(CLONE_NEWIPC);
+ isolated_child();
+ return;
}
- if (write(p1[1], "cont", 5) < 0) {
- tst_resm(TBROK | TERRNO, "write(p1[1], ..) failed");
+ } else {
+ tst_res(TINFO, "Spawning plain process");
+
+ if (!SAFE_FORK()) {
+ shared_child();
+ return;
}
- read(p2[0], buf, 7);
}
+}
- tst_exit();
+static void setup(void)
+{
+ mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
}
+
+static void cleanup(void)
+{
+ if (mqd != -1) {
+ SAFE_MQ_CLOSE(mqd);
+ SAFE_MQ_UNLINK(MQNAME);
+ }
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .forks_child = 1,
+ .options = (struct tst_option[]) {
+ { "m:", &str_op, "Child process isolation <clone|unshare>" },
+ {},
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL
+ },
+};
diff --git a/testcases/kernel/containers/mqns/mqns_03.c b/testcases/kernel/containers/mqns/mqns_03.c
index a7452b970..4a0399ddb 100644
--- a/testcases/kernel/containers/mqns/mqns_03.c
+++ b/testcases/kernel/containers/mqns/mqns_03.c
@@ -1,207 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) International Business Machines Corp., 2009
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Author: Serge Hallyn <serue@us.ibm.com>
-*
-* Check ipcns+sb longevity
-*
-* Mount mqueue fs
-* unshare
-* In unshared process:
-* Create "/mq1" with mq_open()
-* Mount mqueuefs
-* Check that /mq1 exists
-* Create /dev/mqueue/mq2 through vfs (create(2))
-* Umount /dev/mqueue
-* Remount /dev/mqueue
-* Check that both /mq1 and /mq2 exist
-
-***************************************************************************/
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "mqns.h"
-#include "mqns_helper.h"
-
-char *TCID = "posixmq_namespace_03";
-int TST_TOTAL = 1;
-
-int p1[2];
-int p2[2];
-
-#define FNAM1 DEV_MQUEUE2 SLASH_MQ1
-#define FNAM2 DEV_MQUEUE2 SLASH_MQ2
-
-int check_mqueue(void *vtest)
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (c) Serge Hallyn <serue@us.ibm.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test mqueuefs from an isolated/forked process namespace.
+ *
+ * [Algorithm]
+ *
+ * Inside new IPC namespace:
+ *
+ * - mq_open() /MQ1
+ * - mount mqueue inside the temporary folder
+ * - check for /MQ1 existance
+ * - creat() /MQ2 inside the temporary folder
+ * - umount
+ * - mount mqueue inside the temporary folder
+ * - check /MQ1 existance
+ * - check /MQ2 existance
+ * - umount
+ */
+
+#include "tst_test.h"
+#include "lapi/sched.h"
+#include "tst_safe_posix_ipc.h"
+#include "tst_safe_stdio.h"
+#include "tst_safe_macros.h"
+
+#define CHECK_MQ_OPEN_RET(x) ((x) >= 0 || ((x) == -1 && errno != EMFILE))
+
+#define DEVDIR "ltp_mqueue"
+#define MQNAME1 "/MQ1"
+#define MQNAME2 "/MQ2"
+#define MQUEUE1 DEVDIR MQNAME1
+#define MQUEUE2 DEVDIR MQNAME2
+
+static char *str_op;
+
+static void check_mqueue(void)
{
- char buf[30];
- mqd_t mqd;
int rc;
- struct stat statbuf;
+ mqd_t mqd;
- (void) vtest;
+ tst_res(TINFO, "Creating %s mqueue from within child process", MQNAME1);
- close(p1[1]);
- close(p2[0]);
+ mqd = TST_RETRY_FUNC(
+ mq_open(MQNAME1, O_RDWR | O_CREAT | O_EXCL, 0777, NULL),
+ CHECK_MQ_OPEN_RET);
+ if (mqd == -1)
+ tst_brk(TBROK | TERRNO, "mq_open failed");
- if (read(p1[0], buf, 3) != 3) { /* go */
- perror("read failed");
- exit(1);
- }
+ SAFE_MQ_CLOSE(mqd);
- mqd = tst_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDWR | O_CREAT | O_EXCL,
- 0755, NULL);
- if (mqd == -1) {
- write(p2[1], "mqfail", 7);
- exit(1);
- }
+ tst_res(TINFO, "Mount %s from within child process", DEVDIR);
- mq_close(mqd);
+ SAFE_MOUNT("mqueue", DEVDIR, "mqueue", 0, NULL);
- rc = mount("mqueue", DEV_MQUEUE2, "mqueue", 0, NULL);
- if (rc == -1) {
- write(p2[1], "mount1", 7);
- exit(1);
- }
+ if (access(MQUEUE1, F_OK))
+ tst_res(TFAIL, MQUEUE1 " does not exist at first mount");
+ else
+ tst_res(TPASS, MQUEUE1 " exists at first mount");
- rc = stat(FNAM1, &statbuf);
- if (rc == -1) {
- write(p2[1], "stat1", 6);
- exit(1);
- }
+ tst_res(TINFO, "Creating %s from within child process", MQUEUE2);
- rc = creat(FNAM2, 0755);
- if (rc == -1) {
- write(p2[1], "creat", 6);
- exit(1);
- }
+ rc = SAFE_CREAT(MQUEUE2, 0755);
+ SAFE_CLOSE(rc);
- close(rc);
+ tst_res(TINFO, "Mount %s from within child process a second time", DEVDIR);
- rc = umount(DEV_MQUEUE2);
- if (rc == -1) {
- write(p2[1], "umount", 7);
- exit(1);
- }
+ SAFE_UMOUNT(DEVDIR);
+ SAFE_MOUNT("mqueue", DEVDIR, "mqueue", 0, NULL);
- rc = mount("mqueue", DEV_MQUEUE2, "mqueue", 0, NULL);
- if (rc == -1) {
- write(p2[1], "mount2", 7);
- exit(1);
- }
+ if (access(MQUEUE1, F_OK))
+ tst_res(TFAIL, MQUEUE1 " does not exist at second mount");
+ else
+ tst_res(TPASS, MQUEUE1 " exists at second mount");
- rc = stat(FNAM1, &statbuf);
- if (rc == -1) {
- write(p2[1], "stat2", 7);
- exit(1);
- }
+ if (access(MQUEUE2, F_OK))
+ tst_res(TFAIL, MQUEUE2 " does not exist at second mount");
+ else
+ tst_res(TPASS, MQUEUE2 " exists at second mount");
- rc = stat(FNAM2, &statbuf);
- if (rc == -1) {
- write(p2[1], "stat3", 7);
- exit(1);
- }
+ SAFE_UMOUNT(DEVDIR);
- write(p2[1], "done", 5);
+ SAFE_MQ_UNLINK(MQNAME1);
+ SAFE_MQ_UNLINK(MQNAME2);
+}
- exit(0);
+static void run(void)
+{
+ const struct tst_clone_args clone_args = {
+ .flags = CLONE_NEWIPC,
+ .exit_signal = SIGCHLD
+ };
+
+ if (str_op && !strcmp(str_op, "clone")) {
+ tst_res(TINFO, "Spawning isolated process");
+
+ if (!SAFE_CLONE(&clone_args)) {
+ check_mqueue();
+ return;
+ }
+ } else if (str_op && !strcmp(str_op, "unshare")) {
+ tst_res(TINFO, "Spawning unshared process");
+
+ if (!SAFE_FORK()) {
+ SAFE_UNSHARE(CLONE_NEWIPC);
+ check_mqueue();
+ return;
+ }
+ }
}
static void setup(void)
{
- tst_require_root();
- check_mqns();
+ if (!str_op || (strcmp(str_op, "clone") && strcmp(str_op, "unshare")))
+ tst_brk(TCONF, "Please specify clone|unshare child isolation");
+
+ SAFE_MKDIR(DEVDIR, 0755);
}
-int main(int argc, char *argv[])
+static void cleanup(void)
{
- int r;
- char buf[30];
- int use_clone = T_UNSHARE;
-
- setup();
-
- if (argc == 2 && strcmp(argv[1], "-clone") == 0) {
- tst_resm(TINFO, "Testing posix mq namespaces through clone(2)");
- use_clone = T_CLONE;
- } else
- tst_resm(TINFO,
- "Testing posix mq namespaces through unshare(2)");
-
- if (pipe(p1) == -1 || pipe(p2) == -1)
- tst_brkm(TBROK | TERRNO, NULL, "pipe failed");
-
- /* fire off the test */
- r = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mqueue, NULL);
- if (r < 0) {
- tst_brkm(TBROK | TERRNO, NULL, "failed clone/unshare");
- }
-
- tst_resm(TINFO, "Checking correct umount+remount of mqueuefs");
-
- mkdir(DEV_MQUEUE2, 0755);
-
- close(p1[0]);
- close(p2[1]);
- write(p1[1], "go", 3);
-
- read(p2[0], buf, 7);
- r = TFAIL;
- if (!strcmp(buf, "mqfail")) {
- tst_resm(TFAIL, "child process could not create mqueue");
- goto fail;
- } else if (!strcmp(buf, "mount1")) {
- tst_resm(TFAIL, "child process could not mount mqueue");
- goto fail;
- } else if (!strcmp(buf, "stat1x")) {
- tst_resm(TFAIL, "mq created by child is not in mqueuefs");
- goto fail;
- } else if (!strcmp(buf, "creat")) {
- tst_resm(TFAIL, "child couldn't creat mq through mqueuefs");
- goto fail;
- } else if (!strcmp(buf, "umount")) {
- tst_resm(TFAIL, "child couldn't umount mqueuefs");
- goto fail;
- } else if (!strcmp(buf, "mount2")) {
- tst_resm(TFAIL, "child couldn't remount mqueuefs");
- goto fail;
- } else if (!strcmp(buf, "stat2")) {
- tst_resm(TFAIL,
- "mq_open()d file gone after remount of mqueuefs");
- goto fail;
- } else if (!strcmp(buf, "stat3")) {
- tst_resm(TFAIL,
- "creat(2)'d file gone after remount of mqueuefs");
- goto fail;
- }
+ if (!access(MQUEUE1, F_OK))
+ SAFE_MQ_UNLINK(MQNAME1);
- tst_resm(TPASS, "umount+remount of mqueuefs remounted the right fs");
+ if (!access(MQUEUE2, F_OK))
+ SAFE_MQ_UNLINK(MQNAME2);
- r = 0;
-fail:
- umount(DEV_MQUEUE2);
- rmdir(DEV_MQUEUE2);
- tst_exit();
+ if (tst_is_mounted(DEVDIR))
+ SAFE_UMOUNT(DEVDIR);
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_tmpdir = 1,
+ .options = (struct tst_option[]) {
+ { "m:", &str_op, "Child process isolation <clone|unshare>" },
+ {},
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL
+ },
+};
diff --git a/testcases/kernel/containers/mqns/mqns_04.c b/testcases/kernel/containers/mqns/mqns_04.c
index d07a85c04..2d943e1b6 100644
--- a/testcases/kernel/containers/mqns/mqns_04.c
+++ b/testcases/kernel/containers/mqns/mqns_04.c
@@ -1,187 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) International Business Machines Corp., 2009
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Author: Serge Hallyn <serue@us.ibm.com>
-*
-* Check mqueuefs lifetime
-* . parent creates /dev/mqueue2
-* . child mounts mqueue there
-* . child does mq_open("/ab")
-* . parent checks for /dev/mqueue2
-* . child exits
-* . parent checks for /dev/mqueue2
-* . parent tries 'touch /dev/mqueue2/dd' -> should fail
-* . parent umounts /dev/mqueue2
-
-***************************************************************************/
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (c) Serge Hallyn <serue@us.ibm.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test mqueuefs manipulation from child/parent namespaces.
+ *
+ * [Algorithm]
+ *
+ * - parent creates mqueue folder in <tmpdir>
+ * - child mq_open() /MQ1 mqueue
+ * - child mounts mqueue there
+ * - parent checks for <tmpdir>/mqueue/MQ1 existence
+ * - child exits
+ * - parent checks for <tmpdir>/mqueue/MQ1 existence
+ * - parent tries 'touch <tmpdir>/mqueue/MQ2' -> should fail
+ * - parent umount mqueuefs
+ */
+
#include <sys/wait.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "mqns.h"
-#include "mqns_helper.h"
+#include "tst_test.h"
+#include "lapi/sched.h"
+#include "tst_safe_posix_ipc.h"
+#include "tst_safe_stdio.h"
+#include "tst_safe_macros.h"
-char *TCID = "posixmq_namespace_04";
-int TST_TOTAL = 1;
+#define CHECK_MQ_OPEN_RET(x) ((x) >= 0 || ((x) == -1 && errno != EMFILE))
-int p1[2];
-int p2[2];
+#define DEVDIR "ltp_mqueue"
+#define MQNAME1 "/MQ1"
+#define MQNAME2 "/MQ2"
+#define MQUEUE1 DEVDIR MQNAME1
+#define MQUEUE2 DEVDIR MQNAME2
-#define FNAM1 DEV_MQUEUE2 SLASH_MQ1
-#define FNAM2 DEV_MQUEUE2 SLASH_MQ2
+static char *str_op;
-int check_mqueue(void *vtest)
+static void check_mqueue(void)
{
- char buf[30];
mqd_t mqd;
- int rc;
- (void) vtest;
+ tst_res(TINFO, "Creating %s mqueue from within child process", MQNAME1);
- close(p1[1]);
- close(p2[0]);
+ mqd = TST_RETRY_FUNC(
+ mq_open(MQNAME1, O_RDWR | O_CREAT | O_EXCL, 0755, NULL),
+ CHECK_MQ_OPEN_RET);
+ if (mqd == -1)
+ tst_brk(TBROK | TERRNO, "mq_open failed");
- read(p1[0], buf, 3); /* go */
+ SAFE_MQ_CLOSE(mqd);
- mqd = tst_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDWR | O_CREAT | O_EXCL,
- 0755, NULL);
- if (mqd == -1) {
- write(p2[1], "mqfail", 7);
- tst_exit();
- }
+ tst_res(TINFO, "Mount %s from within child process", DEVDIR);
- mq_close(mqd);
+ SAFE_MOUNT("mqueue", DEVDIR, "mqueue", 0, NULL);
+
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+}
- rc = mount("mqueue", DEV_MQUEUE2, "mqueue", 0, NULL);
- if (rc == -1) {
- perror("mount");
- write(p2[1], "mount", 6);
- tst_exit();
+static void run(void)
+{
+ const struct tst_clone_args clone_args = {
+ .flags = CLONE_NEWIPC,
+ .exit_signal = SIGCHLD
+ };
+
+ if (str_op && !strcmp(str_op, "clone")) {
+ tst_res(TINFO, "Spawning isolated process");
+
+ if (!SAFE_CLONE(&clone_args)) {
+ check_mqueue();
+ return;
+ }
+ } else if (str_op && !strcmp(str_op, "unshare")) {
+ tst_res(TINFO, "Spawning unshared process");
+
+ if (!SAFE_FORK()) {
+ SAFE_UNSHARE(CLONE_NEWIPC);
+ check_mqueue();
+ return;
+ }
}
- write(p2[1], "go", 3);
- read(p1[0], buf, 3);
+ TST_CHECKPOINT_WAIT(0);
- tst_exit();
-}
+ if (access(MQUEUE1, F_OK))
+ tst_res(TFAIL, MQUEUE1 " can't be accessed from parent");
+ else
+ tst_res(TPASS, MQUEUE1 " can be accessed from parent");
-static void setup(void)
-{
- tst_require_root();
- check_mqns();
-}
+ TST_CHECKPOINT_WAKE(0);
-int main(int argc, char *argv[])
-{
- int rc;
- int status;
- char buf[30];
- struct stat statbuf;
- int use_clone = T_UNSHARE;
-
- setup();
-
- if (argc == 2 && strcmp(argv[1], "-clone") == 0) {
- tst_resm(TINFO,
- "Testing posix mq namespaces through clone(2).");
- use_clone = T_CLONE;
- } else
- tst_resm(TINFO,
- "Testing posix mq namespaces through unshare(2).");
-
- if (pipe(p1) == -1) {
- perror("pipe");
- exit(EXIT_FAILURE);
- }
- if (pipe(p2) == -1) {
- perror("pipe");
- exit(EXIT_FAILURE);
- }
+ tst_res(TINFO, "Waiting child to exit");
- mkdir(DEV_MQUEUE2, 0755);
+ tst_reap_children();
- tst_resm(TINFO, "Checking mqueue filesystem lifetime");
+ if (access(MQUEUE1, F_OK))
+ tst_res(TFAIL, MQUEUE1 " can't be accessed from parent");
+ else
+ tst_res(TPASS, MQUEUE1 " can be accessed from parent");
- /* fire off the test */
- rc = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mqueue, NULL);
- if (rc < 0) {
- tst_resm(TFAIL, "failed clone/unshare");
- goto fail;
- }
+ tst_res(TINFO, "Try to create %s from parent", MQUEUE2);
- close(p1[0]);
- close(p2[1]);
- write(p1[1], "go", 3);
-
- read(p2[0], buf, 7);
- if (!strcmp(buf, "mqfail")) {
- tst_resm(TFAIL, "child process could not create mqueue");
- goto fail;
- } else if (!strcmp(buf, "mount")) {
- tst_resm(TFAIL, "child process could not mount mqueue");
- goto fail;
- }
+ TST_EXP_FAIL(creat(MQUEUE2, 0755), EACCES);
- rc = stat(FNAM1, &statbuf);
- if (rc == -1) {
- perror("stat");
- write(p1[1], "go", 3);
- tst_resm(TFAIL, "parent could not see child's created mq");
- goto fail;
- }
- write(p1[1], "go", 3);
+ SAFE_UMOUNT(DEVDIR);
+}
- rc = wait(&status);
- if (rc == -1) {
- perror("wait");
- tst_resm(TFAIL, "error while parent waited on child to exit");
- goto fail;
- }
- if (!WIFEXITED(status)) {
- tst_resm(TFAIL, "Child did not exit normally (status %d)",
- status);
- goto fail;
- }
- rc = stat(FNAM1, &statbuf);
- if (rc == -1) {
- tst_resm(TFAIL,
- "parent's view of child's mq died with child");
- goto fail;
- }
+static void setup(void)
+{
+ if (!str_op || (strcmp(str_op, "clone") && strcmp(str_op, "unshare")))
+ tst_brk(TCONF, "Please specify clone|unshare child isolation");
- rc = creat(FNAM2, 0755);
- if (rc != -1) {
- tst_resm(TFAIL,
- "parent was able to create a file in dead child's mqfs");
- goto fail;
- }
+ SAFE_MKDIR(DEVDIR, 0755);
+}
- tst_resm(TPASS, "Child mqueue fs still visible for parent");
+static void cleanup(void)
+{
+ if (!access(MQUEUE1, F_OK))
+ SAFE_MQ_UNLINK(MQNAME1);
-fail:
- umount(DEV_MQUEUE2);
- rmdir(DEV_MQUEUE2);
+ if (!access(MQUEUE2, F_OK))
+ SAFE_MQ_UNLINK(MQNAME2);
- tst_exit();
+ if (tst_is_mounted(DEVDIR))
+ SAFE_UMOUNT(DEVDIR);
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .options = (struct tst_option[]) {
+ { "m:", &str_op, "Child process isolation <clone|unshare>" },
+ {},
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL
+ },
+};
diff --git a/testcases/kernel/containers/mqns/mqns_helper.h b/testcases/kernel/containers/mqns/mqns_helper.h
deleted file mode 100644
index 03f50aa36..000000000
--- a/testcases/kernel/containers/mqns/mqns_helper.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2009
- * Copyright (c) Nadia Derbey, 2009
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: Serge Hallyn <serue@us.ibm.com>
- ***************************************************************************/
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <mqueue.h>
-#include "../libclone/libclone.h"
-#include "lapi/syscalls.h"
-#include "safe_macros.h"
-#include "test.h"
-
-static int dummy_child(void *v)
-{
- (void) v;
- return 0;
-}
-
-static void check_mqns(void)
-{
- int pid, status;
- mqd_t mqd;
-
- mq_unlink("/checkmqnsenabled");
- mqd =
- mq_open("/checkmqnsenabled", O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
- if (mqd == -1)
- tst_brkm(TCONF, NULL, "mq_open check failed");
-
- mq_close(mqd);
- mq_unlink("/checkmqnsenabled");
-
- pid = do_clone_unshare_test(T_CLONE, CLONE_NEWIPC, dummy_child, NULL);
- if (pid == -1)
- tst_brkm(TCONF | TERRNO, NULL, "CLONE_NEWIPC not supported");
-
- SAFE_WAIT(NULL, &status);
-}
diff --git a/testcases/kernel/containers/netns/Makefile b/testcases/kernel/containers/netns/Makefile
index 3cc2b4ae7..a8edd31b8 100644
--- a/testcases/kernel/containers/netns/Makefile
+++ b/testcases/kernel/containers/netns/Makefile
@@ -2,12 +2,12 @@
# Copyright (c) International Business Machines Corp., 2008
# Author: Veerendra <veeren@linux.vnet.ibm.com>
# Copyright (c) 2015 Red Hat, Inc.
+# Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
-LDLIBS := -lclone -lltp
+INSTALL_TARGETS := *.sh
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/containers/netns/netns_lib.sh b/testcases/kernel/containers/netns/netns_lib.sh
index 79e90336a..f6977f729 100755
--- a/testcases/kernel/containers/netns/netns_lib.sh
+++ b/testcases/kernel/containers/netns/netns_lib.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2022 Petr Vorel <pvorel@suse.cz>
-# Copyright (c) Linux Test Project, 2014-2021
+# Copyright (c) Linux Test Project, 2014-2023
# Copyright (c) 2015 Red Hat, Inc.
TST_NEEDS_ROOT=1
@@ -20,7 +20,7 @@ TST_NET_SKIP_VARIABLE_INIT=1
IPV4_NET16_UNUSED="10.23"
IPV6_NET32_UNUSED="fd00:23"
-# Set to "net" for ns_create/ns_exec as their options requires
+# Set to "net" for tst_ns_create/tst_ns_exec as their options requires
# to specify a namespace type. Empty for ip command.
NS_TYPE=
@@ -28,7 +28,7 @@ NS_TYPE=
tping=
# Network namespaces handles for manipulating and executing commands inside
-# namespaces. For 'ns_exec' handles are PIDs of daemonized processes running
+# namespaces. For 'tst_ns_exec' handles are PIDs of daemonized processes running
# in namespaces.
NS_HANDLE0=
NS_HANDLE1=
@@ -40,7 +40,7 @@ NS_HANDLE1=
IFCONF_IN6_ARG=
# Program which will be used to enter and run other commands inside a network namespace.
-# (ns_exec|ip)
+# (tst_ns_exec|ip)
NS_EXEC="ip"
# Communication type between kernel and user space for basic setup: enabling and
@@ -54,7 +54,7 @@ do_cleanup=
netns_parse_args()
{
case $1 in
- e) NS_EXEC="ns_exec" ;;
+ e) NS_EXEC="tst_ns_exec" ;;
I) COMM_TYPE="ioctl"; tst_require_cmds ifconfig ;;
esac
}
@@ -63,7 +63,7 @@ netns_usage()
{
echo "usage: $0 [ -e ] [ -I ]"
echo "OPTIONS"
- echo "-e Use ns_exec instead of ip"
+ echo "-e Use tst_ns_exec instead of ip"
echo "-I Test ioctl (with ifconfig) instead of netlink (with ip)"
}
@@ -72,9 +72,6 @@ netns_setup()
if [ "$NS_EXEC" = "ip" ]; then
netns_ip_setup
else
- setns_check
- [ $? -eq 32 ] && tst_brk TCONF "setns not supported"
-
NS_TYPE="net"
netns_ns_exec_setup
fi
@@ -108,7 +105,7 @@ netns_cleanup()
fi
}
-# Sets up NS_EXEC to use 'ns_exec', creates two network namespaces and stores
+# Sets up NS_EXEC to use 'tst_ns_exec', creates two network namespaces and stores
# their handles into NS_HANDLE0 and NS_HANDLE1 variables (in this case handles
# are PIDs of daemonized processes running in these namespaces). Virtual
# ethernet device is then created for each namespace.
@@ -116,15 +113,15 @@ netns_ns_exec_setup()
{
local ret
- NS_EXEC="ns_exec"
+ NS_EXEC="tst_ns_exec"
- NS_HANDLE0=$(ns_create $NS_TYPE)
+ NS_HANDLE0=$(tst_ns_create $NS_TYPE)
if [ $? -eq 1 ]; then
tst_res TINFO "$NS_HANDLE0"
tst_brk TBROK "unable to create a new network namespace"
fi
- NS_HANDLE1=$(ns_create $NS_TYPE)
+ NS_HANDLE1=$(tst_ns_create $NS_TYPE)
if [ $? -eq 1 ]; then
tst_res TINFO "$NS_HANDLE1"
tst_brk TBROK "unable to create a new network namespace"
@@ -133,7 +130,7 @@ netns_ns_exec_setup()
$NS_EXEC $NS_HANDLE0 $NS_TYPE ip link add veth0 type veth peer name veth1 || \
tst_brk TBROK "unable to create veth pair devices"
- $NS_EXEC $NS_HANDLE0 $NS_TYPE ns_ifmove veth1 $NS_HANDLE1
+ $NS_EXEC $NS_HANDLE0 $NS_TYPE tst_ns_ifmove veth1 $NS_HANDLE1
ret=$?
[ $ret -eq 0 ] && return
[ $ret -eq 32 ] && tst_brk TCONF "IFLA_NET_NS_PID not supported"
diff --git a/testcases/kernel/containers/netns/netns_sysfs.sh b/testcases/kernel/containers/netns/netns_sysfs.sh
index 179242721..814274fd0 100755
--- a/testcases/kernel/containers/netns/netns_sysfs.sh
+++ b/testcases/kernel/containers/netns/netns_sysfs.sh
@@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) Köry Maincent <kory.maincent@bootlin.com> 2020
# Copyright (c) 2015 Red Hat, Inc.
+# Copyright (c) Linux Test Project, 2015-2023
#
# Tests that a separate network namespace cannot affect sysfs contents
# of the main namespace.
@@ -18,12 +19,7 @@ do_setup()
DUMMYDEV_HOST="dummy_test0"
DUMMYDEV="dummy_test1"
- setns_check
- if [ $? -eq 32 ]; then
- tst_brk TCONF "setns not supported"
- fi
-
- NS_HANDLE=$(ns_create $NS_TYPE)
+ NS_HANDLE=$(tst_ns_create $NS_TYPE)
if [ $? -eq 1 ]; then
tst_res TINFO "$NS_HANDLE"
tst_brk TBROK "unable to create a new network namespace"
@@ -32,10 +28,10 @@ do_setup()
ip link add $DUMMYDEV_HOST type dummy || \
tst_brk TBROK "failed to add a new (host) dummy device"
- ns_exec $NS_HANDLE $NS_TYPE mount --make-rprivate /sys
- ns_exec $NS_HANDLE $NS_TYPE ip link add $DUMMYDEV type dummy || \
+ tst_ns_exec $NS_HANDLE $NS_TYPE mount --make-rprivate /sys
+ tst_ns_exec $NS_HANDLE $NS_TYPE ip link add $DUMMYDEV type dummy || \
tst_brk TBROK "failed to add a new dummy device"
- ns_exec $NS_HANDLE $NS_TYPE mount -t sysfs none /sys 2>/dev/null
+ tst_ns_exec $NS_HANDLE $NS_TYPE mount -t sysfs none /sys 2>/dev/null
}
do_cleanup()
@@ -47,8 +43,8 @@ do_cleanup()
do_test()
{
- EXPECT_PASS ns_exec $NS_HANDLE $NS_TYPE test -e /sys/class/net/$DUMMYDEV
- EXPECT_FAIL ns_exec $NS_HANDLE $NS_TYPE test -e /sys/class/net/$DUMMYDEV_HOST
+ EXPECT_PASS tst_ns_exec $NS_HANDLE $NS_TYPE test -e /sys/class/net/$DUMMYDEV
+ EXPECT_FAIL tst_ns_exec $NS_HANDLE $NS_TYPE test -e /sys/class/net/$DUMMYDEV_HOST
EXPECT_FAIL test -e /sys/class/net/$DUMMYDEV
}
diff --git a/testcases/kernel/containers/pidns/Makefile b/testcases/kernel/containers/pidns/Makefile
index 5f8383c3c..180bc7c90 100644
--- a/testcases/kernel/containers/pidns/Makefile
+++ b/testcases/kernel/containers/pidns/Makefile
@@ -4,8 +4,7 @@
top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
-LDLIBS := -lpthread -lrt -lclone $(LDLIBS)
+LDLIBS := -lrt $(LDLIBS)
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/containers/pidns/pidns01.c b/testcases/kernel/containers/pidns/pidns01.c
index 5080b6fad..8b856ec90 100644
--- a/testcases/kernel/containers/pidns/pidns01.c
+++ b/testcases/kernel/containers/pidns/pidns01.c
@@ -8,7 +8,7 @@
/*\
* [Description]
*
- * Clone a process with CLONE_NEWNS flag and check:
+ * Clone a process with CLONE_NEWPID flag and check:
*
* - child process ID must be 1
* - parent process ID must be 0
@@ -17,29 +17,36 @@
#include "tst_test.h"
#include "lapi/sched.h"
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
pid_t cpid, ppid;
- cpid = getpid();
+ cpid = tst_getpid();
ppid = getppid();
- TST_EXP_PASS(cpid == 1);
- TST_EXP_PASS(ppid == 0);
-
- return 0;
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
}
static void run(void)
{
- int ret;
-
- ret = ltp_clone_quick(CLONE_NEWNS | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK | TERRNO, "clone failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
+ }
}
static struct tst_test test = {
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_PID_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/pidns/pidns02.c b/testcases/kernel/containers/pidns/pidns02.c
index b8913d3f6..f23178cb6 100644
--- a/testcases/kernel/containers/pidns/pidns02.c
+++ b/testcases/kernel/containers/pidns/pidns02.c
@@ -7,7 +7,7 @@
/*\
* [Description]
*
- * Clone a process with CLONE_NEWNS flag and check:
+ * Clone a process with CLONE_NEWPID flag and check:
*
* - child session ID must be 1
* - parent process group ID must be 1
@@ -16,29 +16,37 @@
#include "tst_test.h"
#include "lapi/sched.h"
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
- pid_t sid, pgid;
+ TST_EXP_EQ_LI(getsid(0), 0);
+ TST_EXP_EQ_LI(getpgid(0), 0);
- sid = getsid(0);
- pgid = getpgid(0);
+ tst_res(TINFO, "setsid()");
+ SAFE_SETSID();
- TST_EXP_PASS(sid == 1);
- TST_EXP_PASS(pgid == 1);
-
- return 0;
+ TST_EXP_EQ_LI(getsid(0), 1);
+ TST_EXP_EQ_LI(getpgid(0), 1);
}
static void run(void)
{
- int ret;
-
- ret = ltp_clone_quick(CLONE_NEWNS | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK | TERRNO, "clone failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
+ }
}
static struct tst_test test = {
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_PID_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/pidns/pidns03.c b/testcases/kernel/containers/pidns/pidns03.c
index 122ba7891..d662ca9d5 100644
--- a/testcases/kernel/containers/pidns/pidns03.c
+++ b/testcases/kernel/containers/pidns/pidns03.c
@@ -17,7 +17,7 @@
#define PROCDIR "proc"
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
char proc_self[10];
@@ -28,8 +28,6 @@ static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
SAFE_UMOUNT(PROCDIR);
TST_EXP_PASS(strcmp(proc_self, "1"), PROCDIR"/self contains 1:");
-
- return 0;
}
static void setup(void)
@@ -45,11 +43,15 @@ static void cleanup(void)
static void run(void)
{
- int ret;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
- ret = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK | TERRNO, "clone failed");
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
+ }
}
static struct tst_test test = {
@@ -57,5 +59,10 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.needs_root = 1,
+ .forks_child = 1,
.needs_tmpdir = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_PID_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/pidns/pidns04.c b/testcases/kernel/containers/pidns/pidns04.c
index 9ac0e5aca..bed75a082 100644
--- a/testcases/kernel/containers/pidns/pidns04.c
+++ b/testcases/kernel/containers/pidns/pidns04.c
@@ -1,150 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
+ * Copyright (C) International Business Machines Corp., 2008
+ * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-* File: pidns04.c
-*
-* Description:
-* The pidns04.c testcase builds into the ltp framework to verify
-* the basic functionality of PID Namespace.
-*
-* Verify that:
-* 1. When parent clone a process with flag CLONE_NEWPID, the process ID of
-* child should be one.
-*
-* 2. When parent clone a process with flag CLONE_NEWPID, the parent process ID
-* of should be zero.
-*
-* 3. The container init process (one), should not get killed by the SIGKILL in
-* the childNS
-*
-* Total Tests:
-*
-* Test Name: pidns04
-*
-* Test Assertion & Strategy:
-*
-* From main() clone a new child process with passing the clone_flag as
-* CLONE_NEWPID.
-* The container init, should not get killed by the SIGKILL inside the child NS.
-* Usage: <for command-line>
-* pidns04
-*
-* History:
-*
-* FLAG DATE NAME DESCRIPTION
-* 08/10/08 Veerendra C <vechandr@in.ibm.com> Verifies killing of cont init.
-*
-*******************************************************************************/
-#define _GNU_SOURCE 1
-#include <sys/wait.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#define CLEANUP cleanup
-#include "pidns_helper.h"
-#include "test.h"
-
-#define INIT_PID 1
-#define CHILD_PID 1
-#define PARENT_PID 0
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag and check that child container does
+ * not get kill itself with SIGKILL.
+ */
-char *TCID = "pidns04";
-int TST_TOTAL = 1;
-int fd[2];
+#include <sys/wait.h>
+#include "tst_test.h"
+#include "lapi/sched.h"
-/*
- * child_fn1() - Inside container
-*/
-static int child_fn1(void *ttype)
+static void child_func(void)
{
- int exit_val;
- pid_t cpid, ppid;
- cpid = getpid();
- ppid = getppid();
- char mesg[] = "I was not killed !";
- /* Child process closes up read side of pipe */
- close(fd[0]);
+ pid_t cpid = tst_getpid();
+ pid_t ppid = getppid();
- /* Comparing the values to make sure pidns is created correctly */
- if ((cpid == CHILD_PID) && (ppid == PARENT_PID)) {
- printf("PIDNS test is running inside container\n");
- kill(INIT_PID, SIGKILL);
- /* Verifying whether the container init is not killed, "
- If so writing into the pipe created in the parent NS" */
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
- /* Send "mesg" through the write side of pipe */
- write(fd[1], mesg, (strlen(mesg) + 1));
- exit_val = 0;
- } else {
- printf("got unexpected result of cpid=%d ppid=%d\n",
- cpid, ppid);
- exit_val = 1;
- }
- exit(exit_val);
-}
+ tst_res(TINFO, "Trying to kill container from within container");
-static void setup(void)
-{
- tst_require_root();
- check_newpid();
+ SAFE_KILL(1, SIGKILL);
+
+ tst_res(TINFO, "Container is up and running");
}
-int main(void)
+static void run(void)
{
- int nbytes, status;
- char readbuffer[80];
-
- setup();
-
- pipe(fd);
- TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID, child_fn1, NULL));
- if (TEST_RETURN == -1) {
- tst_brkm(TFAIL | TTERRNO, CLEANUP, "clone failed");
- } else if (wait(&status) == -1) {
- tst_brkm(TFAIL | TERRNO, CLEANUP, "wait failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+ pid_t pid;
+
+ pid = SAFE_CLONE(&args);
+ if (!pid) {
+ child_func();
+ return;
}
- /* Parent process closes up write side of pipe */
- close(fd[1]);
- /* Read in a string from the pipe */
- nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
-
- if (0 <= nbytes) {
- tst_resm(TPASS, "Container init : %s", readbuffer);
- } else {
- tst_brkm(TFAIL, CLEANUP,
- "Container init is killed by SIGKILL !!!");
- }
-
- if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
- tst_resm(TFAIL, "Container init pid exited abnormally");
- } else if (WIFSIGNALED(status)) {
- tst_resm(TFAIL, "Container init pid got killed by signal %d",
- WTERMSIG(status));
- }
- CLEANUP();
-
- tst_exit();
-
+ tst_reap_children();
}
-static void cleanup(void)
-{
- close(fd[0]);
-}
+static struct tst_test test = {
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns05.c b/testcases/kernel/containers/pidns/pidns05.c
index 79e146e36..0e7739aaa 100644
--- a/testcases/kernel/containers/pidns/pidns05.c
+++ b/testcases/kernel/containers/pidns/pidns05.c
@@ -1,256 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
-*
-* Assertion:
-* a) Create a container.
-* b) Create many levels of child containers inside this container.
-* c) Now do kill -9 init , outside of the container.
-* d) This should kill all the child containers.
-* (containers created at the level below)
-*
-* Description:
-* 1. Parent process clone a process with flag CLONE_NEWPID
-* 2. The container will recursively loop and creates 4 more containers.
-* 3. All the container init's goes into sleep(), waiting to be terminated.
-* 4. The parent process will kill child[3] by passing SIGKILL
-* 5. Now parent process, verifies the child containers 4 & 5 are destroyed.
-* 6. If they are killed then
-* Test passed
-* else Test failed.
-*
-* Test Name: pidns05
-*
-* History:
-*
-* FLAG DATE NAME DESCRIPTION
-* 31/10/08 Veerendra C <vechandr@in.ibm.com> Verifies killing of NestedCont's
-*
-*******************************************************************************/
-#define _GNU_SOURCE 1
+ * Copyright (c) Veerendra C <vechandr@in.ibm.com>, 2008
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag and create many levels of child
+ * containers. Then kill container init process from parent and check if all
+ * containers have been killed.
+ */
+
#include <sys/wait.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "pidns_helper.h"
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
+#include "lapi/sched.h"
-#define INIT_PID 1
-#define CINIT_PID 1
-#define PARENT_PID 0
#define MAX_DEPTH 5
-char *TCID = "pidns05";
-int TST_TOTAL = 1;
-int fd[2];
-
-int max_pid(void)
-{
- FILE *fp;
- int ret;
-
- fp = fopen("/proc/sys/kernel/pid_max", "r");
- if (fp != NULL) {
- fscanf(fp, "%d", &ret);
- fclose(fp);
- } else {
- tst_resm(TBROK, "Cannot open /proc/sys/kernel/pid_max");
- ret = -1;
- }
- return ret;
-}
+static struct tst_clone_args clone_args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD
+};
+static pid_t pid_max;
-/* find_cinit_pids() iteratively finds the pid's having same PGID as its parent.
- * Input parameter - Accepts pointer to pid_t : To copy the pid's matching.
- * Returns - the number of pids matched.
-*/
-int find_cinit_pids(pid_t * pids)
+static void child_func(int *level)
{
- int next = 0, pid_max, i;
- pid_t parentpid, pgid, pgid2;
+ pid_t cpid, ppid;
- pid_max = max_pid();
- parentpid = getpid();
- pgid = getpgid(parentpid);
+ cpid = tst_getpid();
+ ppid = getppid();
- /* The loop breaks, when the loop counter reaches the parentpid value */
- for (i = parentpid + 1; i != parentpid; i++) {
- if (i > pid_max)
- i = 2;
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
- pgid2 = getpgid(i);
- if (pgid2 == pgid) {
- pids[next] = i;
- next++;
- }
+ if (*level >= MAX_DEPTH) {
+ TST_CHECKPOINT_WAKE(0);
+ return;
}
- return next;
-}
-
-/*
-* create_nested_container() Recursively create MAX_DEPTH nested containers
-*/
-int create_nested_container(void *vtest)
-{
- int exit_val;
- int ret, count, *level;
- pid_t cpid, ppid;
- cpid = getpid();
- ppid = getppid();
- char mesg[] = "Nested Containers are created";
- level = (int *)vtest;
- count = *level;
+ (*level)++;
- /* Child process closes up read side of pipe */
- close(fd[0]);
-
- /* Comparing the values to make sure pidns is created correctly */
- if (cpid != CINIT_PID || ppid != PARENT_PID) {
- printf("Got unexpected cpid and/or ppid (cpid=%d ppid=%d)\n",
- cpid, ppid);
- exit_val = 1;
- }
- if (count > 1) {
- count--;
- ret = do_clone_unshare_test(T_CLONE, CLONE_NEWPID,
- create_nested_container,
- (void *)&count);
- if (ret == -1) {
- printf("clone failed; errno = %d : %s\n",
- ret, strerror(ret));
- exit_val = 1;
- } else
- exit_val = 0;
- } else {
- /* Sending mesg, 'Nested containers created' through the pipe */
- write(fd[1], mesg, (strlen(mesg) + 1));
- exit_val = 0;
+ if (!SAFE_CLONE(&clone_args)) {
+ child_func(level);
+ return;
}
- close(fd[1]);
pause();
-
- return exit_val;
}
-void kill_nested_containers()
+static int find_cinit_pids(pid_t *pids)
{
- int orig_count, new_count, status = 0, i;
- pid_t pids[MAX_DEPTH];
- pid_t pids_new[MAX_DEPTH];
+ int pid;
+ int next = 0;
+ pid_t parentpid, pgid, pgid2;
- orig_count = find_cinit_pids(pids);
- kill(pids[MAX_DEPTH - 3], SIGKILL);
- sleep(1);
+ parentpid = tst_getpid();
+ pgid = SAFE_GETPGID(parentpid);
- /* After killing child container, getting the New PID list */
- new_count = find_cinit_pids(pids_new);
+ for (pid = 2; pid < pid_max; pid++) {
+ if (pid == parentpid)
+ continue;
- /* Verifying that the child containers were destroyed when parent is killed */
- if (orig_count - 2 != new_count)
- status = -1;
+ pgid2 = getpgid(pid);
- for (i = 0; i < new_count; i++) {
- if (pids[i] != pids_new[i])
- status = -1;
+ if (pgid2 == pgid) {
+ pids[next] = pid;
+ next++;
+ }
}
- if (status == 0)
- tst_resm(TPASS, "The number of containers killed are %d",
- orig_count - new_count);
- else
- tst_resm(TFAIL, "Failed to kill the sub-containers of "
- "the container %d", pids[MAX_DEPTH - 3]);
-
- /* Loops through the containers created to exit from sleep() */
- for (i = 0; i < MAX_DEPTH; i++) {
- kill(pids[i], SIGKILL);
- waitpid(pids[i], &status, 0);
- }
+ return next;
}
static void setup(void)
{
- tst_require_root();
- check_newpid();
+ SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%d\n", &pid_max);
}
-int main(void)
+static void run(void)
{
- int ret, nbytes, status;
- char readbuffer[80];
- pid_t pid, pgid;
- int count = MAX_DEPTH;
-
- setup();
+ int i, status, children;
+ int level = 0;
+ pid_t pids_new[MAX_DEPTH];
+ pid_t pids[MAX_DEPTH];
+ pid_t pid;
- /*
- * XXX (garrcoop): why in the hell is this fork-wait written this way?
- * This doesn't add up with the pattern used for the rest of the tests,
- * so I'm pretty damn sure this test is written incorrectly.
- */
- pid = fork();
- if (pid == -1) {
- tst_brkm(TBROK | TERRNO, NULL, "fork failed");
- } else if (pid != 0) {
- /*
- * NOTE: use waitpid so that we know we're waiting for the
- * _top-level_ child instead of a spawned subcontainer.
- *
- * XXX (garrcoop): Might want to mask SIGCHLD in the top-level
- * child too, or not *shrugs*.
- */
- if (waitpid(pid, &status, 0) == -1) {
- perror("wait failed");
- }
- if (WIFEXITED(status))
- exit(WEXITSTATUS(status));
- else
- exit(status);
+ pid = SAFE_CLONE(&clone_args);
+ if (!pid) {
+ child_func(&level);
+ return;
}
- /* To make all the containers share the same PGID as its parent */
- setpgid(0, 0);
+ TST_CHECKPOINT_WAIT(0);
- pid = getpid();
- pgid = getpgid(pid);
- SAFE_PIPE(NULL, fd);
+ TST_EXP_POSITIVE(find_cinit_pids(pids));
- TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID,
- create_nested_container, (void *)&count));
- if (TEST_RETURN == -1) {
- tst_brkm(TFAIL | TTERRNO, NULL, "clone failed");
- }
+ SAFE_KILL(pid, SIGKILL);
+ SAFE_WAITPID(0, &status, 0);
- close(fd[1]);
- /* Waiting for the MAX_DEPTH number of containers to be created */
- nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
- close(fd[0]);
- if (nbytes > 0)
- tst_resm(TINFO, " %d %s", MAX_DEPTH, readbuffer);
- else
- tst_brkm(TFAIL, NULL, "unable to create %d containers",
- MAX_DEPTH);
+ children = find_cinit_pids(pids_new);
- /* Kill the container created */
- kill_nested_containers();
+ if (children > 0) {
+ tst_res(TFAIL, "%d children left after sending SIGKILL", children);
- tst_exit();
+ for (i = 0; i < MAX_DEPTH; i++) {
+ kill(pids[i], SIGKILL);
+ waitpid(pids[i], &status, 0);
+ }
+
+ return;
+ }
+
+ tst_res(TPASS, "No children left after sending SIGKILL to the first child");
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns06.c b/testcases/kernel/containers/pidns/pidns06.c
index d6623941a..c85a875e4 100644
--- a/testcases/kernel/containers/pidns/pidns06.c
+++ b/testcases/kernel/containers/pidns/pidns06.c
@@ -1,133 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
/*
-* Copyright (c) International Business Machines Corp., 2008
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-*************************************************************************
-* Description:
-* Testcase tries killing of the parent namespace pid by the container-init.
-* It also tries killing of non-existent PID, by the container-init.
-* Returns Success if Unable to kill, and proper error number is set.
-* else Returns Failure
-*
-* Steps:
-* 1. Parent process clone a process with flag CLONE_NEWPID
-* 2. The pid of the parent namespace is passed to the container.
-* 3. Container receieves the PID and passes SIGKILL to this PID.
-* 4. If kill() is unsuccessful and the errno is set to 'No Such process'
-* then sets PASS
-* else,
-* sets FAIL
-* 5. It also verifies by passing SIGKILL to FAKE_PID
-* 6. If kill() is unsuccessful and the errno is set to 'No Such process'
-* then sets PASS
-* else,
-* sets FAIL
-*
-*******************************************************************************/
-#define _GNU_SOURCE 1
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <assert.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include "pidns_helper.h"
-#include "test.h"
+ * Copyright (C) International Business Machines Corp., 2008
+ * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-#define CINIT_PID 1
-#define PARENT_PID 0
-#define FAKE_PID -1
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag and check that parent process can't
+ * be killed from child namespace.
+ */
-char *TCID = "pidns06";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "lapi/sched.h"
-/*
- * kill_pid_in_childfun()
- * Cont-init tries to kill the parent-process using parent's global Pid.
- * Also checks passing SIGKILL to non existent PID in the container.
- */
-static int kill_pid_in_childfun(void *vtest)
+static void child_func(int pid)
{
- int cpid, ppid, *par_pid;
- int ret = 0;
- cpid = getpid();
- ppid = getppid();
- par_pid = (int *)vtest;
+ pid_t cpid = tst_getpid();
+ pid_t ppid = getppid();
- /* Checking the values to make sure pidns is created correctly */
- if (cpid != CINIT_PID || ppid != PARENT_PID) {
- printf("Unexpected result for Container: init "
- "pid=%d ppid=%d\n", cpid, ppid);
- exit(1);
- }
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
- /*
- * While trying kill() of the pid of the parent namespace..
- * Check to see if the errno was set to the expected, value of 3 : ESRCH
- */
- ret = kill(*par_pid, SIGKILL);
- if (ret == -1 && errno == ESRCH) {
- printf("Container: killing parent pid=%d failed as expected "
- "with ESRCH\n", *par_pid);
- } else {
- printf("Container: killing parent pid=%d, didn't fail as "
- "expected with ESRCH (%d) and a return value of -1. Got "
- "%d (\"%s\") and a return value of %d instead.\n",
- *par_pid, ESRCH, errno, strerror(errno), ret);
- exit(1);
- }
- /*
- * While killing non-existent pid in the container,
- * Check to see if the errno was set to the expected, value of 3 : ESRCH
- */
- ret = kill(FAKE_PID, SIGKILL);
- if (ret == -1 && errno == ESRCH) {
- printf("Container: killing non-existent pid failed as expected "
- "with ESRCH\n");
- } else {
- printf("Container: killing non-existent pid, didn't fail as "
- "expected with ESRCH (%d) and a return value of -1. Got "
- "%d (\"%s\") and a return value of %d instead.\n",
- ESRCH, errno, strerror(errno), ret);
- exit(1);
- }
+ tst_res(TINFO, "Trying to kill parent from within container");
- exit(0);
+ TST_EXP_FAIL(kill(pid, SIGKILL), ESRCH);
}
-static void setup(void)
+static void run(void)
{
- tst_require_root();
- check_newpid();
-}
-
-int main(void)
-{
- int status;
-
- setup();
-
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
pid_t pid = getpid();
- tst_resm(TINFO, "Parent: Passing the pid of the process %d", pid);
- TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID, kill_pid_in_childfun,
- (void *)&pid));
- if (TEST_RETURN == -1) {
- tst_brkm(TFAIL | TTERRNO, NULL, "clone failed");
- } else if (wait(&status) == -1) {
- tst_brkm(TFAIL | TERRNO, NULL, "wait failed");
+ if (!SAFE_CLONE(&args)) {
+ child_func(pid);
+ return;
}
-
- tst_exit();
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns10.c b/testcases/kernel/containers/pidns/pidns10.c
index b38b9fd18..c2a9094b6 100644
--- a/testcases/kernel/containers/pidns/pidns10.c
+++ b/testcases/kernel/containers/pidns/pidns10.c
@@ -1,112 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
-* File: pidns10.c
-* *
-* * Description:
-* * The pidns10.c testcase verifies inside the container, if kill(-1, signal)
-* * fails with ESRCH when there are no processes in container.
-* *
-* * Test Assertion & Strategy:
-* * Create a PID namespace container.
-* * Invoke kill(-1, SIGUSR1) inside container and check return code and error.
-* * kill() should have failed;except swapper & init, no process is inside.
-* *
-* * Usage: <for command-line>
-* * pidns10
-* *
-* * History:
-* * DATE NAME DESCRIPTION
-* * 13/11/08 Gowrishankar M Creation of this test.
-* * <gowrishankar.m@in.ibm.com>
-*
-******************************************************************************/
-#define _GNU_SOURCE 1
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include "pidns_helper.h"
-#include "test.h"
-
-char *TCID = "pidns10";
-int TST_TOTAL = 1;
+ * Copyright (C) International Business Machines Corp., 2008
+ * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-int child_fn(void *);
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag and check that killing subprocesses
+ * from child namespace will raise ESRCH error.
+ */
-#define CHILD_PID 1
-#define PARENT_PID 0
+#include "tst_test.h"
+#include "lapi/sched.h"
-/*
- * child_fn() - Inside container
- */
-int child_fn(void *arg)
+static void child_func(void)
{
- int exit_val, ret;
- pid_t pid, ppid;
+ pid_t cpid = tst_getpid();
+ pid_t ppid = getppid();
- /* Set process id and parent pid */
- pid = getpid();
- ppid = getppid();
- if (pid != CHILD_PID || ppid != PARENT_PID) {
- printf("cinit: pidns was not created.\n");
- return 1;
- }
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
- if ((ret = kill(-1, SIGUSR1)) == -1 && errno == ESRCH) {
- printf("cinit: kill(-1, sig) failed with -1 / ESRCH as "
- "expected\n");
- exit_val = 0;
- } else {
- printf("cinit: kill(-1, sig) didn't fail with -1 / ESRCH "
- "(%d); failed with %d / %d instead", ESRCH, ret, errno);
- exit_val = 1;
- }
- exit(exit_val);
-}
+ tst_res(TINFO, "Trying to kill all subprocesses from within container");
-static void setup(void)
-{
- tst_require_root();
- check_newpid();
+ TST_EXP_FAIL(kill(-1, SIGKILL), ESRCH);
}
-int main(void)
+static void run(void)
{
- int status;
- pid_t pid;
-
- setup();
-
- pid = getpid();
-
- /* Container creation on PID namespace */
- TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID, child_fn, NULL));
- if (TEST_RETURN == -1) {
- tst_brkm(TBROK | TTERRNO, NULL, "clone failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
}
-
- sleep(1);
- if (wait(&status) < 0)
- tst_resm(TWARN, "parent: waitpid() failed.");
-
- if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
- tst_resm(TBROK, "container was terminated abnormally");
-
- tst_exit();
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns12.c b/testcases/kernel/containers/pidns/pidns12.c
index fb1ec90ca..1811dbc36 100644
--- a/testcases/kernel/containers/pidns/pidns12.c
+++ b/testcases/kernel/containers/pidns/pidns12.c
@@ -25,11 +25,11 @@ static void child_signal_handler(LTP_ATTRIBUTE_UNUSED int sig, siginfo_t *si, LT
sig_pid = si->si_pid;
}
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
struct sigaction sa;
- TST_EXP_EQ_LI(getpid(), 1);
+ TST_EXP_EQ_LI(tst_getpid(), 1);
TST_EXP_EQ_LI(getppid(), 0);
sa.sa_flags = SA_SIGINFO;
@@ -41,21 +41,25 @@ static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
TST_EXP_EQ_LI(sig_pid, 0);
-
- return 0;
}
static void run(void)
{
- int ret;
-
- ret = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK | TERRNO, "clone failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+ int pid;
+
+ pid = SAFE_CLONE(&args);
+ if (!pid) {
+ child_func();
+ return;
+ }
TST_CHECKPOINT_WAIT(0);
- SAFE_KILL(ret, SIGUSR1);
+ SAFE_KILL(pid, SIGUSR1);
TST_CHECKPOINT_WAKE(0);
}
@@ -63,5 +67,10 @@ static void run(void)
static struct tst_test test = {
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_PID_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/pidns/pidns13.c b/testcases/kernel/containers/pidns/pidns13.c
index 6a155027c..65fcc4443 100644
--- a/testcases/kernel/containers/pidns/pidns13.c
+++ b/testcases/kernel/containers/pidns/pidns13.c
@@ -42,7 +42,7 @@ static void child_signal_handler(int sig, siginfo_t *si,
void *unused LTP_ATTRIBUTE_UNUSED)
{
tst_res(TWARN, "cinit(pid %d): Caught signal! sig=%d, si_fd=%d, si_code=%d",
- getpid(), sig, si->si_fd, si->si_code);
+ tst_getpid(), sig, si->si_fd, si->si_code);
}
static void child_fn(unsigned int cinit_no)
@@ -54,7 +54,7 @@ static void child_fn(unsigned int cinit_no)
pid_t pid, ppid;
int flags;
- pid = tst_syscall(__NR_getpid);
+ pid = tst_getpid();
ppid = getppid();
if (pid != CHILD_PID || ppid != PARENT_PID)
tst_brk(TBROK, "cinit%u: pidns not created.", cinit_no);
@@ -104,7 +104,10 @@ static void child_fn(unsigned int cinit_no)
static void run(void)
{
- const struct tst_clone_args cargs = { CLONE_NEWPID, SIGCHLD };
+ const struct tst_clone_args cargs = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
SAFE_PIPE(pipe_fd);
diff --git a/testcases/kernel/containers/pidns/pidns16.c b/testcases/kernel/containers/pidns/pidns16.c
index 2ee61065a..313b0a097 100644
--- a/testcases/kernel/containers/pidns/pidns16.c
+++ b/testcases/kernel/containers/pidns/pidns16.c
@@ -1,157 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
-
-* * Test Assertion.
-* *----------------
-* * kill -USR1 container_init
-* * - from the parent process and also inside a container
-* * - Where init has defined a custom handler for USR1
-* * - Should call the handler and
-* * - Verify whether the signal handler is called from the proper process.
-* *
-* * Description:
-* * Create PID namespace container.
-* * Container init defines the handler for SIGUSR1 and waits indefinetly.
-* * Parent sends SIGUSR1 to container init.
-* * The signal handler is handled and the cont-init resumes normally.
-* * From the container, again the signal SIGUSR1 is sent.
-* * In the sig-handler check if it's invoked from correct pid(parent/container)
-* * If cont-init wakes up properly -
-* * it will return expected value at exit which is verified at the end.
-* *
-* * History:
-* * DATE NAME DESCRIPTION
-* * 04/11/08 Veerendra C <vechandr@in.ibm.com> Verifying cont init kill -USR1
-*
-*******************************************************************************/
-#include "config.h"
+ * Copyright (c) International Business Machines Corp., 2007
+ * 04/11/08 Veerendra C <vechandr@in.ibm.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag and verifies that siginfo->si_pid is
+ * set to 0 if sender (parent process) sent the signal. Then send signal from
+ * container itself and check if siginfo->si_pid is set to 1.
+ */
#define _GNU_SOURCE 1
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <sys/types.h>
#include <signal.h>
-#include <unistd.h>
-#include "pidns_helper.h"
-#include "test.h"
-
-#define CHILD_PID 1
-#define PARENT_PID 0
+#include "tst_test.h"
+#include "lapi/sched.h"
-char *TCID = "pidns16";
-int TST_TOTAL = 3;
+static volatile int signal_pid;
-void child_signal_handler(int sig, siginfo_t * si, void *unused)
+static void child_signal_handler(LTP_ATTRIBUTE_UNUSED int sig, siginfo_t *si, LTP_ATTRIBUTE_UNUSED void *unused)
{
- static int c = 1;
- pid_t expected_pid;
-
- /* Verifying from which process the signal handler is signalled */
-
- switch (c) {
- case 1:
- expected_pid = PARENT_PID;
- break;
- case 2:
- expected_pid = CHILD_PID;
- break;
- default:
- tst_resm(TBROK, "child should NOT be signalled 3+ times");
- return;
- }
-
- if (si->si_pid == expected_pid)
- tst_resm(TPASS, "child is signalled from expected pid %d",
- expected_pid);
- else
- tst_resm(TFAIL, "child is signalled from unexpected pid %d,"
- " expecting pid %d", si->si_pid, expected_pid);
-
- c++;
+ signal_pid = si->si_pid;
}
-/*
- * child_fn() - Inside container
- */
-int child_fn(void *ttype)
+static void child_func(void)
{
struct sigaction sa;
- pid_t pid, ppid;
+ pid_t cpid, ppid;
- /* Set process id and parent pid */
- pid = getpid();
+ cpid = tst_getpid();
ppid = getppid();
- if ((pid != CHILD_PID) || (ppid != PARENT_PID))
- tst_resm(TBROK, "pidns is not created.");
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
+
+ tst_res(TINFO, "Catching SIGUSR1 signal");
- /* Set signal handler for SIGUSR1, also mask other signals */
sa.sa_flags = SA_SIGINFO;
- sigemptyset(&sa.sa_mask);
+ SAFE_SIGFILLSET(&sa.sa_mask);
sa.sa_sigaction = child_signal_handler;
- if (sigaction(SIGUSR1, &sa, NULL) == -1)
- tst_resm(TBROK, "%d: sigaction() failed", pid);
-
- pause();
- tst_resm(TINFO, "Container: Resumed after receiving SIGUSR1 "
- "from parentNS ");
- if (kill(pid, SIGUSR1) != 0) {
- tst_resm(TFAIL, "kill(SIGUSR1) fails.");
- }
- tst_resm(TINFO, "Container: Resumed after sending SIGUSR1 "
- "from container itself");
- _exit(10);
-}
+ SAFE_SIGACTION(SIGUSR1, &sa, NULL);
-static void setup(void)
-{
- tst_require_root();
- check_newpid();
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+ TST_EXP_EQ_LI(signal_pid, 0);
+
+ tst_res(TINFO, "Sending SIGUSR1 from container itself");
+
+ SAFE_KILL(cpid, SIGUSR1);
+
+ TST_EXP_EQ_LI(signal_pid, 1);
}
-/***********************************************************************
-* M A I N
-***********************************************************************/
-int main()
+static void run(void)
{
- int status;
- pid_t cpid;
-
- setup();
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+ pid_t pid;
- cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL);
+ signal_pid = -1;
- if (cpid < 0) {
- tst_resm(TBROK, "clone() failed.");
+ pid = SAFE_CLONE(&args);
+ if (!pid) {
+ child_func();
+ return;
}
- sleep(1);
- if (kill(cpid, SIGUSR1) != 0) {
- tst_resm(TFAIL, "kill(SIGUSR1) fails.");
- }
- sleep(1);
- if (waitpid(cpid, &status, 0) < 0)
- tst_resm(TWARN, "waitpid() failed.");
-
- if ((WIFEXITED(status)) && (WEXITSTATUS(status) == 10))
- tst_resm(TPASS, "container init continued successfuly, "
- "after handling signal -USR1");
- else
- tst_resm(TFAIL, "c-init failed to continue after "
- "passing kill -USR1");
- tst_exit();
+ TST_CHECKPOINT_WAIT(0);
+
+ tst_res(TINFO, "Sending SIGUSR1 from parent");
+
+ SAFE_KILL(pid, SIGUSR1);
+
+ TST_CHECKPOINT_WAKE(0);
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns17.c b/testcases/kernel/containers/pidns/pidns17.c
index cf0c5826f..4633ec14b 100644
--- a/testcases/kernel/containers/pidns/pidns17.c
+++ b/testcases/kernel/containers/pidns/pidns17.c
@@ -1,162 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
-* File: pidns17.c
-* *
-* * Description:
-* * The pidns17.c testcase verifies inside the container, if kill(-1, SIGUSR1)
-* * terminates all children running inside.
-* *
-* * Test Assertion & Strategy:
-* * Create a PID namespace container.
-* * Spawn many children inside it.
-* * Invoke kill(-1, SIGUSR1) inside container and check if it terminates
-* * all children.
-* *
-* * Usage: <for command-line>
-* * pidns17
-* *
-* * History:
-* * DATE NAME DESCRIPTION
-* * 13/11/08 Gowrishankar M Creation of this test.
-* * <gowrishankar.m@in.ibm.com>
-*
-******************************************************************************/
-#define _GNU_SOURCE 1
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include "pidns_helper.h"
-#include "test.h"
+ * Copyright (c) International Business Machines Corp., 2007
+ * 13/11/08 Gowrishankar M <gowrishankar.m@in.ibm.com>
+ * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-char *TCID = "pidns17";
-int TST_TOTAL = 1;
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag and spawn many children inside the
+ * container. Then terminate all children and check if they were signaled.
+ */
-int child_fn(void *);
+#include <sys/wait.h>
+#include "tst_test.h"
+#include "lapi/sched.h"
-#define CHILD_PID 1
-#define PARENT_PID 0
+#define CHILDREN_NUM 10
-/*
- * child_fn() - Inside container
- */
-int child_fn(void *arg)
+static void child_func(void)
{
- int children[10], exit_val, i, status;
- pid_t pid, ppid;
+ int children[CHILDREN_NUM], status;
+ unsigned int i;
+ pid_t cpid, ppid;
- /* Set process id and parent pid */
- pid = getpid();
+ cpid = tst_getpid();
ppid = getppid();
- if (pid != CHILD_PID || ppid != PARENT_PID) {
- printf("cinit: pidns was not created\n");
- exit(1);
- }
- exit_val = 0;
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
+
+ tst_res(TINFO, "Spawning %d children", CHILDREN_NUM);
- /* Spawn many children */
- for (i = 0; i < ARRAY_SIZE(children); i++) {
- switch ((children[i] = fork())) {
- case -1:
- perror("fork failed");
- exit_val = 1;
- break;
- case 0:
+ for (i = 0; i < CHILDREN_NUM; i++) {
+ children[i] = SAFE_FORK();
+ if (!children[i]) {
pause();
- /* XXX (garrcoop): why exit with an exit code of 2? */
- exit(2);
- break;
- default:
- /* fork succeeded. */
- break;
+ return;
}
}
- /* wait for last child to get scheduled */
- sleep(1);
- if (kill(-1, SIGUSR1) == -1) {
- perror("cinit: kill(-1, SIGUSR1) failed");
- exit_val = 1;
- }
+ tst_res(TINFO, "Terminate children with SIGUSR1");
- for (i = 0; i < ARRAY_SIZE(children); i++) {
- if (waitpid(children[i], &status, 0) == -1) {
- perror("cinit: waitpid failed");
- kill(children[i], SIGTERM);
- waitpid(children[i], &status, 0);
- exit_val = 1;
- }
- if (!(WIFSIGNALED(status) || WTERMSIG(status) == SIGUSR1)) {
- /*
- * XXX (garrcoop): this status reporting is overly
- * noisy. Someone obviously needs to read the
- * constraints documented in wait(2) a bit more
- * closely -- in particular the relationship between
- * WIFEXITED and WEXITSTATUS, and WIFSIGNALED and
- * WTERMSIG.
- */
- printf("cinit: found a child alive still "
- "%d exit: %d, %d, signal %d, %d", i,
- WIFEXITED(status), WEXITSTATUS(status),
- WIFSIGNALED(status), WTERMSIG(status));
- exit_val = 1;
- }
- }
- if (exit_val == 0)
- printf("cinit: all children have terminated.\n");
+ SAFE_KILL(-1, SIGUSR1);
- exit(exit_val);
-}
+ for (i = 0; i < CHILDREN_NUM; i++) {
+ SAFE_WAITPID(children[i], &status, 0);
-static void setup(void)
-{
- tst_require_root();
- check_newpid();
+ TST_EXP_EQ_LI(WIFSIGNALED(status), 1);
+ TST_EXP_EQ_LI(WTERMSIG(status), SIGUSR1);
+ }
}
-int main(void)
+static void run(void)
{
- int status;
- pid_t pid;
-
- setup();
-
- pid = getpid();
-
- /* Container creation on PID namespace */
- TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID, child_fn, NULL));
- if (TEST_RETURN == -1) {
- tst_brkm(TBROK | TTERRNO, NULL, "clone failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
}
-
- sleep(1);
- if (wait(&status) == -1)
- tst_resm(TFAIL, "waitpid failed");
-
- if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
- tst_resm(TFAIL, "container exited abnormally");
- else if (WIFSIGNALED(status))
- tst_resm(TFAIL,
- "container was signaled with signal = %d",
- WTERMSIG(status));
-
- tst_exit();
-
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns20.c b/testcases/kernel/containers/pidns/pidns20.c
index 9f369699a..914820865 100644
--- a/testcases/kernel/containers/pidns/pidns20.c
+++ b/testcases/kernel/containers/pidns/pidns20.c
@@ -26,18 +26,18 @@ static void child_signal_handler(LTP_ATTRIBUTE_UNUSED int sig, siginfo_t *si, LT
signals++;
}
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_func(void)
{
struct sigaction sa;
sigset_t newset;
pid_t cpid, ppid;
- cpid = getpid();
+ cpid = tst_getpid();
ppid = getppid();
if (cpid != 1 || ppid != 0) {
tst_res(TFAIL, "Got unexpected result of cpid=%d ppid=%d", cpid, ppid);
- return 0;
+ return;
}
SAFE_SIGEMPTYSET(&newset);
@@ -56,30 +56,34 @@ static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
if (signals != 1) {
tst_res(TFAIL, "Received %d signals", signals);
- return 0;
+ return;
}
if (last_signo != SIGUSR1) {
tst_res(TFAIL, "Received %s signal", tst_strsig(last_signo));
- return 0;
+ return;
}
tst_res(TPASS, "Received SIGUSR1 signal after unblock");
-
- return 0;
}
static void run(void)
{
- int ret;
-
- ret = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_func, NULL);
- if (ret < 0)
- tst_brk(TBROK | TERRNO, "clone failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
+ int pid;
+
+ pid = SAFE_CLONE(&args);
+ if (!pid) {
+ child_func();
+ return;
+ }
TST_CHECKPOINT_WAIT(0);
- SAFE_KILL(ret, SIGUSR1);
+ SAFE_KILL(pid, SIGUSR1);
TST_CHECKPOINT_WAKE(0);
}
@@ -87,5 +91,10 @@ static void run(void)
static struct tst_test test = {
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_PID_NS",
+ NULL,
+ },
};
diff --git a/testcases/kernel/containers/pidns/pidns30.c b/testcases/kernel/containers/pidns/pidns30.c
index c8b0806c0..4a8bc5e2b 100644
--- a/testcases/kernel/containers/pidns/pidns30.c
+++ b/testcases/kernel/containers/pidns/pidns30.c
@@ -1,296 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) Bull S.A.S. 2008
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
-* File: pidns30.c
-*
-* Description:
-* This testcase checks if the si_pid is correctly set when a process
-* that has registered for notification on a posix mqueue is in a
-* descendant namespace wrt the process that sends a message to that posix
-* mqueue.
-*
-* Test Assertion & Strategy:
-* Parent Child
-* --------------------------------------------------------------------------
-* Create a POSIX mqueue.
-* Create a PID namespace container.
-* Open that mqueue for reading
-* Register for notification when a
-* message arrives in that mqueue
-* Install a handler for SIGUSR1.
-* Write something to the mqueue.
-* Inside the handler, check that
-* si_pid is set to 0
-*
-* Usage: <for command-line>
-* pidns30
-*
-* History:
-* DATE NAME DESCRIPTION
-* 01/12/08 Nadia Derbey Creation of this test.
-* <Nadia.Derbey@bull.net>
-*
-******************************************************************************/
-#define _GNU_SOURCE 1
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <mqueue.h>
-#include "lapi/syscalls.h"
-#include "pidns_helper.h"
-#include "test.h"
-
-char *TCID = "pidns30";
-int TST_TOTAL = 1;
-
-char *mqname = "mq1";
-int result = TFAIL;
-
-int father_to_child[2];
-int child_to_father[2];
-
-#define CHILD_PID 1
-#define PARENT_PID 0
+ * Copyright (c) Bull S.A.S. 2008
+ * 01/12/08 Nadia Derbey <Nadia.Derbey@bull.net>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-#define MSG "HOW ARE YOU"
-#define MSG_PRIO 1
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag, register notification on a posix
+ * mqueue and send a mqueue message from the parent. Then check if signal
+ * notification contains si_pid of the parent.
+ */
-#define NO_STEP -1
-#define F_STEP_0 0x00
-#define F_STEP_1 0x01
-#define F_STEP_2 0x02
-#define F_STEP_3 0x03
-#define C_STEP_0 0x10
-#define C_STEP_1 0x11
-#define C_STEP_2 0x12
+#define _GNU_SOURCE
+#include <signal.h>
+#include <mqueue.h>
+#include "tst_test.h"
+#include "tst_safe_posix_ipc.h"
+#include "lapi/sched.h"
-mqd_t rc = -1;
-mqd_t mqd = -1;
+#define MQNAME "/LTP_PIDNS30_MQ"
-static void remove_pipe(int *fd)
-{
- close(fd[0]);
- close(fd[1]);
-}
+static mqd_t mqd = -1;
+static siginfo_t info;
+static volatile int received;
static void remove_mqueue(mqd_t mqd)
{
- mq_close(mqd);
- tst_syscall(__NR_mq_unlink, mqname);
-}
+ if (mqd != -1)
+ SAFE_MQ_CLOSE(mqd);
-static void cleanup(void)
-{
- if (mqd != -1) {
- remove_mqueue(mqd);
- }
- if (rc != -1) {
- remove_mqueue(rc);
- }
- remove_pipe(father_to_child);
- remove_pipe(child_to_father);
+ mq_unlink(MQNAME);
}
-static void cleanup_child(void)
+static void child_signal_handler(LTP_ATTRIBUTE_UNUSED int sig, siginfo_t *si, LTP_ATTRIBUTE_UNUSED void *unused)
{
- if (mqd != -1) {
- tst_syscall(__NR_mq_notify, mqd, NULL);
- }
- cleanup();
+ received = 1;
+ memcpy(&info, si, sizeof(info));
}
-/*
- * child_signal_handler() - to handle SIGUSR1
- *
- * XXX (garrcoop): add calls to cleanup_child() -- or should this be handled
- * from the libltp signal handler?
- */
-static void child_signal_handler(int sig, siginfo_t * si, void *unused)
+static void child_func(void)
{
- char buf[256];
- struct mq_attr attr;
-
- if (si->si_signo != SIGUSR1) {
- printf("received signal = %d unexpectedly\n", si->si_signo);
- return;
- }
-
- if (si->si_code != SI_MESGQ) {
- printf("expected signal code SI_MESGQ; got %d instead\n",
- si->si_code);
- return;
- }
-
- if (si->si_pid) {
- printf("expected signal originator PID = 0; got %d instead\n",
- si->si_pid);
- return;
- } else {
- printf("signal originator PID = 0\n");
- result = TPASS;
- }
-
- /*
- * Now read the message - Be silent on errors since this is not the
- * test purpose.
- */
- rc = mq_getattr(si->si_int, &attr);
- if (rc != -1)
- mq_receive(si->si_int, buf, attr.mq_msgsize, NULL);
-}
-
-/*
- * child_fn() - Inside container
- *
- * XXX (garrcoop): add more calls to cleanup_child()?
- */
-int child_fn(void *arg)
-{
- pid_t pid, ppid;
+ pid_t cpid, ppid;
struct sigaction sa;
struct sigevent notif;
- char buf[5];
+ mqd_t mqd_child;
- /* Set process id and parent pid */
- pid = getpid();
+ cpid = tst_getpid();
ppid = getppid();
- if (pid != CHILD_PID || ppid != PARENT_PID) {
- printf("pidns was not created\n");
- return 1;
- }
-
- /* Close the appropriate end of each pipe */
- close(child_to_father[0]);
- close(father_to_child[1]);
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
- while (read(father_to_child[0], buf, 1) != 1)
- sleep(1);
+ TST_CHECKPOINT_WAIT(0);
- mqd = tst_syscall(__NR_mq_open, mqname, O_RDONLY, 0, NULL);
- if (mqd == -1) {
- perror("mq_open failed");
- return 1;
- } else
- printf("mq_open succeeded\n");
+ tst_res(TINFO, "Register notification on posix mqueue");
- /* Register for notification on message arrival */
+ mqd_child = SAFE_MQ_OPEN(MQNAME, O_RDONLY, 0, NULL);
notif.sigev_notify = SIGEV_SIGNAL;
notif.sigev_signo = SIGUSR1;
- notif.sigev_value.sival_int = mqd;
- if (tst_syscall(__NR_mq_notify, mqd, &notif) == -1) {
- perror("mq_notify failed");
- return 1;
- } else
- printf("successfully registered for notification\n");
+ notif.sigev_value.sival_int = mqd_child;
+
+ SAFE_MQ_NOTIFY(mqd_child, &notif);
- /* Define handler for SIGUSR1 */
sa.sa_flags = SA_SIGINFO;
- sigemptyset(&sa.sa_mask);
+ SAFE_SIGEMPTYSET(&sa.sa_mask);
sa.sa_sigaction = child_signal_handler;
- if (sigaction(SIGUSR1, &sa, NULL) == -1) {
- perror("sigaction failed");
- return 1;
- } else
- printf("successfully registered handler for SIGUSR1\n");
-
- /* Ask parent to send a message to the mqueue */
- if (write(child_to_father[1], "c:ok", 5) != 5) {
- perror("write failed");
- return 1;
- }
+ SAFE_SIGACTION(SIGUSR1, &sa, NULL);
- sleep(3);
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
- /* Has parent sent a message? */
- read(father_to_child[0], buf, 5);
- if (strcmp(buf, "f:ok") != 0) {
- printf("parent did not send the message!\n");
- return 1;
- }
- printf("parent is done - cleaning up\n");
-
- cleanup_child();
+ if (received)
+ tst_res(TPASS, "Signal notification has been received");
+ else
+ tst_res(TFAIL, "Signal notification has not been received");
- exit(0);
+ TST_EXP_EQ_LI(info.si_signo, SIGUSR1);
+ TST_EXP_EQ_LI(info.si_code, SI_MESGQ);
+ TST_EXP_EQ_LI(info.si_pid, 0);
}
-static void setup(void)
+static void cleanup(void)
{
- tst_require_root();
- check_newpid();
+ remove_mqueue(mqd);
}
-int main(void)
+static void run(void)
{
- int status;
- char buf[5];
- pid_t cpid;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
- setup();
+ remove_mqueue(mqd);
+ received = 0;
- if (pipe(child_to_father) == -1 || pipe(father_to_child) == -1) {
- tst_brkm(TBROK | TERRNO, cleanup, "pipe failed");
+ if (!SAFE_CLONE(&args)) {
+ child_func();
+ return;
}
- tst_syscall(__NR_mq_unlink, mqname);
-
- /* container creation on PID namespace */
- cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL);
- if (cpid == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
-
- mqd =
- tst_syscall(__NR_mq_open, mqname, O_RDWR | O_CREAT | O_EXCL, 0777,
- NULL);
- if (mqd == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "mq_open failed");
- else
- tst_resm(TINFO, "successfully created posix mqueue");
-
- if (write(father_to_child[1], buf, 1) != 1)
- tst_brkm(TBROK | TERRNO, cleanup, "write failed");
+ mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, 0);
- /* Close the appropriate end of each pipe */
- close(child_to_father[1]);
- close(father_to_child[0]);
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
- /* Is container ready */
- read(child_to_father[0], buf, 5);
- if (strcmp(buf, "c:ok") != 0)
- tst_brkm(TBROK, cleanup,
- "container did not respond as expected!");
-
- rc = mq_send(mqd, MSG, strlen(MSG), MSG_PRIO);
- if (rc == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "mq_send failed");
- else
- tst_resm(TINFO, "mq_send succeeded");
+ tst_res(TINFO, "Send mqueue message");
- /* Tell the child the message has been sent */
- if (write(father_to_child[1], "f:ok", 5) != 5)
- tst_brkm(TBROK | TERRNO, cleanup, "write failed");
+ SAFE_MQ_SEND(mqd, "pippo", 5, 1);
- /* Wait for child to finish */
- if (wait(&status) == -1)
- tst_resm(TBROK | TERRNO, "wait failed");
-
- cleanup();
-
- tst_exit();
+ TST_CHECKPOINT_WAKE(0);
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .cleanup = cleanup,
+ .forks_child = 1,
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns31.c b/testcases/kernel/containers/pidns/pidns31.c
index 8821ec83c..7312f8bdc 100644
--- a/testcases/kernel/containers/pidns/pidns31.c
+++ b/testcases/kernel/containers/pidns/pidns31.c
@@ -1,330 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) Bull S.A.S. 2008
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
-* File: pidns31.c
-*
-* Description:
-* This testcase checks if the si_pid is correctly set when a process
-* that has registered for notification on a posix mqueue is in an
-* ancestor namespace wrt the process that sends a message to that posix
-* mqueue.
-*
-* Test Assertion & Strategy:
-* Parent Child
-* --------------------------------------------------------------------------
-* Create a POSIX mqueue.
-* Create a PID namespace container.
-* Register for notification when a
-* message arrives in that mqueue
-* Install a handler for SIGUSR1.
-* Open that mqueue for writing
-* Write something to the mqueue.
-* Inside the handler, check that
-* si_pid is set to the child's pid
-*
-* Usage: <for command-line>
-* pidns31
-*
-* History:
-* DATE NAME DESCRIPTION
-* 04/12/08 Nadia Derbey Creation of this test.
-* <Nadia.Derbey@bull.net>
-*
-******************************************************************************/
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <mqueue.h>
-#include "lapi/syscalls.h"
-#include "pidns_helper.h"
-#include "test.h"
-
-char *TCID = "pidns31";
-int TST_TOTAL = 1;
-
-char *mqname = "mq1";
-int result = TFAIL;
-
-int father_to_child[2];
-
-#define CHILD_PID 1
-#define PARENT_PID 0
+ * Copyright (c) Bull S.A.S. 2008
+ * 01/12/08 Nadia Derbey <Nadia.Derbey@bull.net>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-#define MSG "HOW ARE YOU"
-#define MSG_PRIO 1
+/*\
+ * [Description]
+ *
+ * Clone a process with CLONE_NEWPID flag, register notification on a posix
+ * mqueue and send a mqueue message from the child. Then check if signal
+ * notification contains si_pid of the child.
+ */
-#define NO_STEP -1
-#define F_STEP_0 0x00
-#define F_STEP_1 0x01
-#define F_STEP_2 0x02
-#define F_STEP_3 0x03
-#define C_STEP_0 0x10
-#define C_STEP_1 0x11
+#define _GNU_SOURCE 1
+#include <signal.h>
+#include <mqueue.h>
+#include "tst_test.h"
+#include "tst_safe_posix_ipc.h"
+#include "lapi/sched.h"
-struct notify_info {
- mqd_t mqd;
- pid_t pid;
-};
+#define MQNAME "/LTP_PIDNS30_MQ"
-static void remove_pipe(int *fd)
-{
- close(fd[0]);
- close(fd[1]);
-}
+static mqd_t mqd = -1;
+static volatile int received;
+static siginfo_t info;
static void remove_mqueue(mqd_t mqd)
{
- mq_close(mqd);
- tst_syscall(__NR_mq_unlink, mqname);
-}
+ if (mqd != -1)
+ SAFE_MQ_CLOSE(mqd);
-/*
- * steps F_STEP_XX : called from main
- * steps C_STEP_XX : called from child_fn
- */
-static void cleanup_resources(int step, mqd_t mqd)
-{
- switch (step) {
- case C_STEP_1:
- close(father_to_child[0]);
- /* fall through */
- case C_STEP_0:
- mq_close(mqd);
- break;
-
- case F_STEP_3:
- remove_mqueue(mqd);
- close(father_to_child[1]);
- break;
-
- case F_STEP_2:
- tst_syscall(__NR_mq_notify, mqd, NULL);
- /* fall through */
- case F_STEP_1:
- remove_mqueue(mqd);
- /* fall through */
- case F_STEP_0:
- remove_pipe(father_to_child);
- break;
- default:
- tst_resm(TWARN, "Unknown code - no resource removed.");
- break;
- }
+ mq_unlink(MQNAME);
}
-/*
- * cleanup_mqueue() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- * step == -1 means no local resource to remove.
- */
-void cleanup_mqueue(int result, int step, mqd_t mqd)
+static void signal_handler(LTP_ATTRIBUTE_UNUSED int sig, siginfo_t *si, LTP_ATTRIBUTE_UNUSED void *unused)
{
- if (step != NO_STEP)
- cleanup_resources(step, mqd);
-
- tst_exit();
+ memcpy(&info, si, sizeof(info));
+ received++;
}
-/*
- * child_fn() - Inside container
- */
-int child_fn(void *arg)
+static void child_func(void)
{
- pid_t pid, ppid;
- mqd_t mqd;
- char buf[5];
+ pid_t cpid, ppid;
+ mqd_t mqd_child;
- /* Set process id and parent pid */
- pid = getpid();
+ cpid = tst_getpid();
ppid = getppid();
- if (pid != CHILD_PID || ppid != PARENT_PID) {
- tst_resm(TBROK, "cinit: pidns is not created");
- cleanup_mqueue(TBROK, NO_STEP, 0);
- }
-
- /* Close the appropriate end of pipe */
- close(father_to_child[1]);
-
- /* Is parent ready to receive a message? */
- read(father_to_child[0], buf, 5);
- if (strcmp(buf, "f:ok")) {
- tst_resm(TBROK, "cinit: parent did not send the message!");
- cleanup_mqueue(TBROK, NO_STEP, 0);
- }
- tst_resm(TINFO, "cinit: my father is ready to receive a message");
-
- mqd = tst_syscall(__NR_mq_open, mqname, O_WRONLY, 0, NULL);
- if (mqd == (mqd_t) - 1) {
- tst_resm(TBROK, "cinit: mq_open() failed (%s)",
- strerror(errno));
- cleanup_mqueue(TBROK, NO_STEP, 0);
- }
- tst_resm(TINFO, "cinit: mq_open succeeded");
-
- if (mq_send(mqd, MSG, strlen(MSG), MSG_PRIO) == (mqd_t) - 1) {
- tst_resm(TBROK, "cinit: mq_send() failed (%s)",
- strerror(errno));
- cleanup_mqueue(TBROK, C_STEP_0, mqd);
- }
- tst_resm(TINFO, "cinit: mq_send() succeeded");
-
- /* Cleanup and exit */
- cleanup_resources(C_STEP_1, mqd);
- exit(0);
-}
+ TST_EXP_EQ_LI(cpid, 1);
+ TST_EXP_EQ_LI(ppid, 0);
-/*
- * father_signal_handler()
- */
-static void father_signal_handler(int sig, siginfo_t * si, void *unused)
-{
- char buf[256];
- struct mq_attr attr;
- struct notify_info *info;
+ TST_CHECKPOINT_WAIT(0);
- if (si->si_signo != SIGUSR1) {
- tst_resm(TBROK, "father: received %s unexpectedly",
- strsignal(si->si_signo));
- return;
- }
-
- if (si->si_code != SI_MESGQ) {
- tst_resm(TBROK, "father: expected signal code SI_MESGQ - "
- "Got %d", si->si_code);
- return;
- }
-
- if (!si->si_ptr) {
- tst_resm(TBROK, "father: expected si_ptr - Got NULL");
- return;
- }
-
- info = (struct notify_info *)si->si_ptr;
-
- if (si->si_pid != info->pid) {
- tst_resm(TFAIL,
- "father: expected signal originator PID = %d - Got %d",
- info->pid, si->si_pid);
- return;
- }
+ tst_res(TINFO, "Send mqueue message from child");
- tst_resm(TPASS, "father: signal originator PID = %d", si->si_pid);
- result = TPASS;
+ mqd_child = SAFE_MQ_OPEN(MQNAME, O_WRONLY, 0, NULL);
+ SAFE_MQ_SEND(mqd_child, "pippo", 5, 1);
- /*
- * Now read the message - Be silent on errors since this is not the
- * test purpose.
- */
- if (!mq_getattr(info->mqd, &attr))
- mq_receive(info->mqd, buf, attr.mq_msgsize, NULL);
+ TST_CHECKPOINT_WAKE(0);
}
-static void setup(void)
+static void cleanup(void)
{
- tst_require_root();
- check_newpid();
+ remove_mqueue(mqd);
}
-/***********************************************************************
-* M A I N
-***********************************************************************/
-
-int main(void)
+static void run(void)
{
pid_t cpid;
- mqd_t mqd;
- struct sigevent notif;
struct sigaction sa;
- int status;
- struct notify_info info;
+ struct sigevent notif;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+ };
- setup();
+ remove_mqueue(mqd);
+ received = 0;
- if (pipe(father_to_child) == -1) {
- tst_resm(TBROK, "parent: pipe() failed. aborting!");
- cleanup_mqueue(TBROK, NO_STEP, 0);
+ cpid = SAFE_CLONE(&args);
+ if (!cpid) {
+ child_func();
+ return;
}
- tst_syscall(__NR_mq_unlink, mqname);
- mqd =
- tst_syscall(__NR_mq_open, mqname, O_RDWR | O_CREAT | O_EXCL, 0777,
- NULL);
- if (mqd == (mqd_t) - 1) {
- tst_resm(TBROK, "parent: mq_open() failed (%s)",
- strerror(errno));
- cleanup_mqueue(TBROK, F_STEP_0, 0);
- }
- tst_resm(TINFO, "parent: successfully created posix mqueue");
+ tst_res(TINFO, "Register notification on posix mqueue");
- /* container creation on PID namespace */
- cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL);
- if (cpid < 0) {
- tst_resm(TBROK, "parent: clone() failed(%s)", strerror(errno));
- cleanup_mqueue(TBROK, F_STEP_1, mqd);
- }
- tst_resm(TINFO, "parent: successfully created child (pid = %d)", cpid);
+ mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
- /* Register for notification on message arrival */
notif.sigev_notify = SIGEV_SIGNAL;
notif.sigev_signo = SIGUSR1;
- info.mqd = mqd;
- info.pid = cpid;
- notif.sigev_value.sival_ptr = &info;
- if (tst_syscall(__NR_mq_notify, mqd, &notif) == (mqd_t) -1) {
- tst_resm(TBROK, "parent: mq_notify() failed (%s)",
- strerror(errno));
- cleanup_mqueue(TBROK, F_STEP_1, mqd);
- }
- tst_resm(TINFO, "parent: successfully registered for notification");
-
- /* Define handler for SIGUSR1 */
- sa.sa_flags = SA_SIGINFO;
- sigemptyset(&sa.sa_mask);
- sa.sa_sigaction = father_signal_handler;
- if (sigaction(SIGUSR1, &sa, NULL) == -1) {
- tst_resm(TBROK, "parent: sigaction() failed(%s)",
- strerror(errno));
- cleanup_mqueue(TBROK, F_STEP_2, mqd);
- }
- tst_resm(TINFO, "parent: successfully registered handler for SIGUSR1");
- /* Close the appropriate end of pipe */
- close(father_to_child[0]);
-
- /* Tell the child a message can be sent */
- if (write(father_to_child[1], "f:ok", 5) != 5) {
- tst_resm(TBROK, "parent: pipe is broken(%s)", strerror(errno));
- cleanup_mqueue(TBROK, F_STEP_2, mqd);
- }
+ SAFE_MQ_NOTIFY(mqd, &notif);
- sleep(3);
+ sa.sa_flags = SA_SIGINFO;
+ SAFE_SIGEMPTYSET(&sa.sa_mask);
+ sa.sa_sigaction = signal_handler;
+ SAFE_SIGACTION(SIGUSR1, &sa, NULL);
- /* Wait for child to finish */
- if (wait(&status) == -1) {
- tst_resm(TBROK, "parent: wait() failed(%s)", strerror(errno));
- cleanup_mqueue(TBROK, F_STEP_1, mqd);
- }
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
- cleanup_mqueue(result, F_STEP_3, mqd);
+ tst_reap_children();
- tst_exit();
+ TST_EXP_EQ_LI(received, 1);
+ TST_EXP_EQ_LI(info.si_signo, SIGUSR1);
+ TST_EXP_EQ_LI(info.si_code, SI_MESGQ);
+ TST_EXP_EQ_LI(info.si_pid, cpid);
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .cleanup = cleanup,
+ .forks_child = 1,
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/containers/pidns/pidns32.c b/testcases/kernel/containers/pidns/pidns32.c
index 3f7df788e..0738369b1 100644
--- a/testcases/kernel/containers/pidns/pidns32.c
+++ b/testcases/kernel/containers/pidns/pidns32.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Huawei Technologies Co., Ltd., 2015
- * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
/*\
@@ -12,32 +12,35 @@
*/
#define _GNU_SOURCE
-
#include <sys/mman.h>
#include "tst_test.h"
+#include "tst_atomic.h"
#include "lapi/sched.h"
#define MAXNEST 32
+static const struct tst_clone_args args = {
+ .flags = CLONE_NEWPID,
+ .exit_signal = SIGCHLD,
+};
static int *level;
-static int child_func(LTP_ATTRIBUTE_UNUSED void *arg)
+static pid_t child_func(void)
{
- pid_t cpid;
- int status;
-
- if (*level == MAXNEST)
- return 0;
+ pid_t cpid = 0;
- (*level)++;
+ if (tst_atomic_inc(level) == MAXNEST)
+ return cpid;
- cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_func, 0);
- if (cpid < 0)
- tst_brk(TBROK | TERRNO, "clone failed");
+ cpid = SAFE_CLONE(&args);
+ if (!cpid) {
+ child_func();
+ return cpid;
+ }
- SAFE_WAITPID(cpid, &status, 0);
+ tst_reap_children();
- return 0;
+ return cpid;
}
static void setup(void)
@@ -45,28 +48,25 @@ static void setup(void)
level = SAFE_MMAP(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
}
-static void run(void)
+static void cleanup(void)
{
- int ret, status;
-
- *level = 1;
-
- ret = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_func, 0);
- if (ret < 0)
- tst_brk(TBROK | TERRNO, "clone failed");
+ SAFE_MUNMAP(level, sizeof(int));
+}
- SAFE_WAITPID(ret, &status, 0);
+static void run(void)
+{
+ *level = 0;
- if (*level < MAXNEST) {
- tst_res(TFAIL, "Nested containers should be %d, but they are %d", MAXNEST, *level);
+ if (!child_func())
return;
- }
- tst_res(TPASS, "All %d containers have been nested", MAXNEST);
+ TST_EXP_EQ_LI(*level, MAXNEST);
}
static struct tst_test test = {
.test_all = run,
.needs_root = 1,
.setup = setup,
+ .cleanup = cleanup,
+ .forks_child = 1,
};
diff --git a/testcases/kernel/containers/pidns/pidns_helper.h b/testcases/kernel/containers/pidns/pidns_helper.h
deleted file mode 100644
index 3b356768f..000000000
--- a/testcases/kernel/containers/pidns/pidns_helper.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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.
-*/
-
-#include "../libclone/libclone.h"
-#include "test.h"
-#include "safe_macros.h"
-
-static int dummy_child(void *v)
-{
- (void) v;
- return 0;
-}
-
-static int check_newpid(void)
-{
- int pid, status;
-
- pid = do_clone_unshare_test(T_CLONE, CLONE_NEWPID, dummy_child, NULL);
- if (pid == -1)
- tst_brkm(TCONF | TERRNO, NULL, "CLONE_NEWPID not supported");
- SAFE_WAIT(NULL, &status);
-
- return 0;
-}
diff --git a/testcases/kernel/containers/share/.gitignore b/testcases/kernel/containers/share/.gitignore
deleted file mode 100644
index 06615d9ea..000000000
--- a/testcases/kernel/containers/share/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-/ns_ifmove
-/ns_create
-/ns_exec
-/setns_check
diff --git a/testcases/kernel/containers/share/Makefile b/testcases/kernel/containers/share/Makefile
deleted file mode 100644
index 962d6889d..000000000
--- a/testcases/kernel/containers/share/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (c) 2015 Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of version 2 the GNU General Public License as
-# 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, see <http://www.gnu.org/licenses/>.
-##############################################################################
-top_srcdir ?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
-
-LDLIBS := -lltp
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/containers/share/ns_create.c b/testcases/kernel/containers/share/ns_create.c
deleted file mode 100644
index 3f09e71e0..000000000
--- a/testcases/kernel/containers/share/ns_create.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright (c) 2015 Red Hat, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of version 2 the GNU General Public License as
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Written by Matus Marhefka <mmarhefk@redhat.com>
- *
- ***********************************************************************
- * Creates a child process in the new specified namespace(s), child is then
- * daemonized and is running in the background. PID of the daemonized child
- * process is printed on the stdout. As the new namespace(s) is(are) maintained
- * by the daemonized child process it(they) can be removed by killing this
- * process.
- *
- */
-
-#define _GNU_SOURCE
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "test.h"
-#include "lapi/sched.h"
-#include "ns_common.h"
-
-char *TCID = "ns_create";
-
-
-void print_help(void)
-{
- int i;
-
- printf("usage: ns_create <%s", params[0].name);
-
- for (i = 1; params[i].name; i++)
- printf("|,%s", params[i].name);
- printf(">\nThe only argument is a comma separated list "
- "of namespaces to create.\nExample: ns_create net,ipc\n");
-}
-
-static int child_fn(void *arg LTP_ATTRIBUTE_UNUSED)
-{
- int i;
-
- if (setsid() == -1) {
- tst_resm(TINFO | TERRNO, "setsid");
- exit(1);
- }
-
- if (chdir("/") == -1) {
- tst_resm(TINFO | TERRNO, "chdir");
- exit(1);
- }
-
- /* close all inherrited file descriptors */
- for (i = 0; i < sysconf(_SC_OPEN_MAX); i++)
- close(i);
-
- pause();
- return 0;
-}
-
-/*
- * ./ns_create <ipc,mnt,net,pid,user,uts>
- */
-int main(int argc, char *argv[])
-{
- int pid, flags;
- char *token;
-
- if (argc < 2) {
- print_help();
- return 1;
- }
-
- flags = 0;
- while ((token = strsep(&argv[1], ","))) {
- struct param *p = get_param(token);
-
- if (!p) {
- tst_resm(TINFO, "Unknown namespace: %s", token);
- print_help();
- return 1;
- }
-
- flags |= p->flag;
- }
-
- pid = ltp_clone_quick(flags | SIGCHLD, child_fn, NULL);
- if (pid == -1) {
- tst_resm(TINFO | TERRNO, "ltp_clone_quick");
- return 1;
- }
-
- printf("%d", pid);
- return 0;
-}
diff --git a/testcases/kernel/containers/share/ns_exec.c b/testcases/kernel/containers/share/ns_exec.c
deleted file mode 100644
index 4abd1063b..000000000
--- a/testcases/kernel/containers/share/ns_exec.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Copyright (c) 2015 Red Hat, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of version 2 the GNU General Public License as
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Written by Matus Marhefka <mmarhefk@redhat.com>
- *
- ***********************************************************************
- * Enters the namespace(s) of a process specified by a PID and then executes
- * the indicated program inside that namespace(s).
- *
- */
-
-#define _GNU_SOURCE
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "test.h"
-#include "lapi/syscalls.h"
-#include "lapi/sched.h"
-#include "ns_common.h"
-
-char *TCID = "ns_exec";
-int ns_fd[NS_TOTAL];
-int ns_fds;
-
-
-void print_help(void)
-{
- int i;
-
- printf("usage: ns_exec <NS_PID> <%s", params[0].name);
-
- for (i = 1; params[i].name; i++)
- printf("|,%s", params[i].name);
- printf("> <PROGRAM> [ARGS]\nSecond argument indicates the types"
- " of a namespaces maintained by NS_PID\nand is specified"
- " as a comma separated list.\nExample: ns_exec 1234 net,ipc"
- " ip a\n");
-}
-
-static int open_ns_fd(const char *pid, const char *ns)
-{
- int fd;
- char file_buf[30];
-
- sprintf(file_buf, "%s/%s/ns/%s", PROC_PATH, pid, ns);
-
- fd = open(file_buf, O_RDONLY);
- if (fd > 0) {
- ns_fd[ns_fds] = fd;
- ++ns_fds;
- return 0;
- } else if (fd == -1 && errno != ENOENT) {
- tst_resm(TINFO | TERRNO, "open");
- return -1;
- }
-
- return 0;
-}
-
-static void close_ns_fd(void)
-{
- int i;
-
- for (i = 0; i < ns_fds; i++)
- close(ns_fd[i]);
-}
-
-static int child_fn(void *arg)
-{
- char **args = (char **)arg;
-
- execvp(args[3], args+3);
- tst_resm(TINFO | TERRNO, "execvp");
- return 1;
-}
-
-/*
- * ./ns_exec <NS_PID> <ipc,mnt,net,pid,user,uts> <PROGRAM> [ARGS]
- */
-int main(int argc, char *argv[])
-{
- int i, rv, pid;
- char *token;
-
- rv = syscall(__NR_setns, -1, 0);
- if (rv == -1 && errno == ENOSYS) {
- tst_resm(TINFO, "setns is not supported in the kernel");
- return 1;
- }
-
- if (argc < 4) {
- print_help();
- return 1;
- }
-
- memset(ns_fd, 0, sizeof(ns_fd));
- while ((token = strsep(&argv[2], ","))) {
- struct param *p = get_param(token);
-
- if (!p) {
- tst_resm(TINFO, "Unknown namespace: %s", token);
- print_help();
- return 1;
- }
-
- if (open_ns_fd(argv[1], token) != 0)
- return 1;
- }
-
- if (ns_fds == 0) {
- tst_resm(TINFO, "no namespace entries in /proc/%s/ns/",
- argv[1]);
- return 1;
- }
-
- for (i = 0; i < ns_fds; i++) {
- if (syscall(__NR_setns, ns_fd[i], 0) == -1) {
- tst_resm(TINFO | TERRNO, "setns");
- close_ns_fd();
- return 1;
- }
- }
-
- pid = ltp_clone_quick(SIGCHLD, (void *)child_fn, (void *)argv);
- if (pid == -1) {
- tst_resm(TINFO | TERRNO, "ltp_clone_quick");
- close_ns_fd();
- return 1;
- }
-
- if (waitpid(pid, &rv, 0) == -1) {
- tst_resm(TINFO | TERRNO, "waitpid");
- return 1;
- }
-
- close_ns_fd();
-
- if (WIFEXITED(rv))
- return WEXITSTATUS(rv);
-
- return 0;
-}
diff --git a/testcases/kernel/containers/share/ns_ifmove.c b/testcases/kernel/containers/share/ns_ifmove.c
deleted file mode 100644
index 12642c6f4..000000000
--- a/testcases/kernel/containers/share/ns_ifmove.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2015 Red Hat, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of version 2 the GNU General Public License as
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Written by Matus Marhefka <mmarhefk@redhat.com>
- *
- ***********************************************************************
- * Moves a network interface to the namespace of a process specified by a PID.
- *
- */
-
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/rtnetlink.h>
-#include <sys/ioctl.h>
-#include <linux/if.h>
-#include <net/ethernet.h>
-#include <arpa/inet.h>
-#include "test.h"
-
-#include "config.h"
-
-char *TCID = "ns_ifmove";
-
-#if HAVE_DECL_IFLA_NET_NS_PID
-
-struct {
- struct nlmsghdr nh;
- struct ifinfomsg ifi;
- char attrbuf[512];
-} req;
-
-
-int get_intf_index_from_name(const char *intf_name)
-{
- struct ifreq ifr;
- int sock_fd;
-
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, intf_name, sizeof(ifr.ifr_name) - 1);
- ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
-
- sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (sock_fd == -1) {
- tst_resm(TINFO | TERRNO, "socket");
- return -1;
- }
-
- /* gets interface index */
- if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) == -1) {
- tst_resm(TINFO | TERRNO, "ioctl");
- close(sock_fd);
- return -1;
- }
-
- close(sock_fd);
- return ifr.ifr_ifindex;
-}
-
-/*
- * ./ns_ifmove <INTERFACE_NAME> <NAMESPACE_PID>
- */
-int main(int argc, char **argv)
-{
- struct rtattr *rta;
- int intf_index, pid, rtnetlink_socket;
-
- if (argc != 3) {
- tst_resm(TINFO, "%s <INTERFACE_NAME> <NAMESPACE_PID>",
- argv[0]);
- return 1;
- }
-
- intf_index = get_intf_index_from_name(argv[1]);
- if (intf_index == -1) {
- tst_resm(TINFO , "unable to get interface index");
- return 1;
- }
-
- pid = atoi(argv[2]);
-
- rtnetlink_socket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
- if (rtnetlink_socket == -1) {
- tst_resm(TINFO | TERRNO, "socket");
- return 1;
- }
-
- memset(&req, 0, sizeof(req));
- req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
- req.nh.nlmsg_flags = NLM_F_REQUEST;
- req.nh.nlmsg_type = RTM_NEWLINK;
- req.ifi.ifi_family = AF_UNSPEC;
- req.ifi.ifi_index = intf_index;
- req.ifi.ifi_change = 0xffffffff;
- rta = (struct rtattr *)(((char *) &req) +
- NLMSG_ALIGN(req.nh.nlmsg_len));
- rta->rta_type = IFLA_NET_NS_PID;
- rta->rta_len = RTA_LENGTH(sizeof(int));
- req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) +
- RTA_LENGTH(sizeof(pid));
- memcpy(RTA_DATA(rta), &pid, sizeof(pid));
-
- if (send(rtnetlink_socket, &req, req.nh.nlmsg_len, 0) == -1) {
- tst_resm(TINFO | TERRNO, "send");
- return 1;
- }
-
- close(rtnetlink_socket);
- return 0;
-}
-
-#else
-
-int main(void)
-{
- tst_brkm(TCONF, NULL, "IFLA_NET_NS_PID not defined in linux/if_link.h");
-}
-
-#endif
diff --git a/testcases/kernel/containers/share/setns_check.c b/testcases/kernel/containers/share/setns_check.c
deleted file mode 100644
index 75aad17f3..000000000
--- a/testcases/kernel/containers/share/setns_check.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (c) 2015 Fujitsu Ltd.
- * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of version 2 the GNU General Public License as
- * 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, see <http://www.gnu.org/licenses/>.
- *
- ***********************************************************************
- * Check for setns() availability, should be called before ns_exec.
- *
- */
-
-#include "test.h"
-#include "lapi/syscalls.h"
-
-char *TCID = "setns_check";
-
-int main(void)
-{
- if (syscall(__NR_setns, -1, 0) == -1 && errno == ENOSYS)
- tst_brkm(TCONF, NULL, "setns is not supported in the kernel");
- else
- return 0;
-}
diff --git a/testcases/kernel/containers/sysvipc/common.h b/testcases/kernel/containers/sysvipc/common.h
index 9b0fc16e9..180cf9bd7 100644
--- a/testcases/kernel/containers/sysvipc/common.h
+++ b/testcases/kernel/containers/sysvipc/common.h
@@ -19,24 +19,7 @@ enum {
T_NONE,
};
-static int dummy_child(void *v)
-{
- (void)v;
- return 0;
-}
-
-static void check_newipc(void)
-{
- int pid, status;
-
- pid = ltp_clone_quick(CLONE_NEWIPC | SIGCHLD, dummy_child, NULL);
- if (pid < 0)
- tst_brk(TCONF | TERRNO, "CLONE_NEWIPC not supported");
-
- SAFE_WAITPID(pid, &status, 0);
-}
-
-static inline int get_clone_unshare_enum(const char* str_op)
+static inline int get_clone_unshare_enum(const char *str_op)
{
int use_clone;
@@ -54,16 +37,22 @@ static inline int get_clone_unshare_enum(const char* str_op)
return use_clone;
}
-static void clone_test(unsigned long clone_flags, int (*fn1)(void *arg), void *arg1)
+static void clone_test(unsigned long clone_flags, void (*fn1)())
{
+ const struct tst_clone_args clone_args = {
+ .flags = clone_flags,
+ .exit_signal = SIGCHLD,
+ };
int pid;
- pid = ltp_clone_quick(clone_flags | SIGCHLD, fn1, arg1);
- if (pid < 0)
- tst_brk(TBROK | TERRNO, "ltp_clone_quick error");
+ pid = SAFE_CLONE(&clone_args);
+ if (!pid) {
+ fn1();
+ exit(0);
+ }
}
-static void unshare_test(unsigned long clone_flags, int (*fn1)(void *arg), void *arg1)
+static void unshare_test(unsigned long clone_flags, void (*fn1)())
{
int pid;
@@ -71,34 +60,33 @@ static void unshare_test(unsigned long clone_flags, int (*fn1)(void *arg), void
if (!pid) {
SAFE_UNSHARE(clone_flags);
- fn1(arg1);
+ fn1();
exit(0);
}
}
-static void plain_test(int (*fn1)(void *arg), void *arg1)
+static void plain_test(void (*fn1)())
{
int pid;
pid = SAFE_FORK();
if (!pid) {
- fn1(arg1);
+ fn1();
exit(0);
}
}
-static void clone_unshare_test(int use_clone, unsigned long clone_flags,
- int (*fn1)(void *arg), void *arg1)
+static void clone_unshare_test(int use_clone, unsigned long clone_flags, void (*fn1)())
{
switch (use_clone) {
case T_NONE:
- plain_test(fn1, arg1);
+ plain_test(fn1);
break;
case T_CLONE:
- clone_test(clone_flags, fn1, arg1);
+ clone_test(clone_flags, fn1);
break;
case T_UNSHARE:
- unshare_test(clone_flags, fn1, arg1);
+ unshare_test(clone_flags, fn1);
break;
default:
tst_brk(TBROK, "%s: bad use_clone option: %d", __FUNCTION__, use_clone);
diff --git a/testcases/kernel/containers/sysvipc/mesgq_nstest.c b/testcases/kernel/containers/sysvipc/mesgq_nstest.c
index 056b5d086..4b12c1ce1 100644
--- a/testcases/kernel/containers/sysvipc/mesgq_nstest.c
+++ b/testcases/kernel/containers/sysvipc/mesgq_nstest.c
@@ -42,7 +42,7 @@ struct msg_buf {
char mtext[80];
};
-static int check_mesgq(LTP_ATTRIBUTE_UNUSED void *vtest)
+static void check_mesgq(void)
{
int id, n;
struct msg_buf msg = {};
@@ -55,7 +55,7 @@ static int check_mesgq(LTP_ATTRIBUTE_UNUSED void *vtest)
else
tst_res(TPASS, "%s: container didn't find mesgq", str_op);
- return 0;
+ return;
}
if (use_clone == T_NONE) {
@@ -68,11 +68,10 @@ static int check_mesgq(LTP_ATTRIBUTE_UNUSED void *vtest)
if (strcmp(msg.mtext, MSG_TEXT))
tst_res(TFAIL, "Received the wrong text message");
- return 0;
+ return;
}
tst_res(TFAIL, "%s: container init process found mesgq", str_op);
- return 0;
}
static void run(void)
@@ -87,16 +86,12 @@ static void run(void)
tst_res(TINFO, "mesgq namespaces test: %s", str_op);
- clone_unshare_test(use_clone, CLONE_NEWIPC, check_mesgq, NULL);
+ clone_unshare_test(use_clone, CLONE_NEWIPC, check_mesgq);
}
static void setup(void)
{
use_clone = get_clone_unshare_enum(str_op);
-
- if (use_clone != T_NONE)
- check_newipc();
-
ipc_id = SAFE_MSGGET(KEY_VAL, IPC_CREAT | IPC_EXCL | 0600);
}
diff --git a/testcases/kernel/containers/sysvipc/msg_comm.c b/testcases/kernel/containers/sysvipc/msg_comm.c
index 238863d9c..3762adb02 100644
--- a/testcases/kernel/containers/sysvipc/msg_comm.c
+++ b/testcases/kernel/containers/sysvipc/msg_comm.c
@@ -38,7 +38,7 @@ struct sysv_msg {
char mtext[1];
};
-static int chld1_msg(LTP_ATTRIBUTE_UNUSED void *arg)
+static void chld1_msg(void)
{
int id;
struct sysv_msg m = {
@@ -66,11 +66,9 @@ static int chld1_msg(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE(0);
SAFE_MSGCTL(id, IPC_RMID, NULL);
-
- return 0;
}
-static int chld2_msg(LTP_ATTRIBUTE_UNUSED void *arg)
+static void chld2_msg(void)
{
int id;
struct sysv_msg m = {
@@ -85,24 +83,17 @@ static int chld2_msg(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
SAFE_MSGCTL(id, IPC_RMID, NULL);
-
- return 0;
}
static void run(void)
{
- clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld1_msg, NULL);
- clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld2_msg, NULL);
-}
-
-static void setup(void)
-{
- check_newipc();
+ clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld1_msg);
+ clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld2_msg);
}
static struct tst_test test = {
.test_all = run,
- .setup = setup,
.needs_root = 1,
.needs_checkpoints = 1,
+ .forks_child = 1,
};
diff --git a/testcases/kernel/containers/sysvipc/sem_comm.c b/testcases/kernel/containers/sysvipc/sem_comm.c
index 3323ec09f..d8f0956a7 100644
--- a/testcases/kernel/containers/sysvipc/sem_comm.c
+++ b/testcases/kernel/containers/sysvipc/sem_comm.c
@@ -33,7 +33,7 @@
#define TESTKEY 124426L
-static int chld1_sem(LTP_ATTRIBUTE_UNUSED void *arg)
+static void chld1_sem(void)
{
int id;
struct sembuf sm = {
@@ -56,11 +56,9 @@ static int chld1_sem(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
SAFE_SEMCTL(id, 0, IPC_RMID);
-
- return 0;
}
-static int chld2_sem(LTP_ATTRIBUTE_UNUSED void *arg)
+static void chld2_sem(void)
{
int id;
struct sembuf sm = {
@@ -93,24 +91,17 @@ static int chld2_sem(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE(0);
SAFE_SEMCTL(id, 0, IPC_RMID);
-
- return 0;
}
static void run(void)
{
- clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld1_sem, NULL);
- clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld2_sem, NULL);
-}
-
-static void setup(void)
-{
- check_newipc();
+ clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld1_sem);
+ clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld2_sem);
}
static struct tst_test test = {
.test_all = run,
- .setup = setup,
.needs_root = 1,
.needs_checkpoints = 1,
+ .forks_child = 1,
};
diff --git a/testcases/kernel/containers/sysvipc/sem_nstest.c b/testcases/kernel/containers/sysvipc/sem_nstest.c
index ac1dae443..35d55cbac 100644
--- a/testcases/kernel/containers/sysvipc/sem_nstest.c
+++ b/testcases/kernel/containers/sysvipc/sem_nstest.c
@@ -35,7 +35,7 @@ static char *str_op;
static int use_clone;
static int ipc_id = -1;
-static int check_semaphore(LTP_ATTRIBUTE_UNUSED void *vtest)
+static void check_semaphore(void)
{
int id;
@@ -47,7 +47,7 @@ static int check_semaphore(LTP_ATTRIBUTE_UNUSED void *vtest)
else
tst_res(TPASS, "%s: container didn't find semaphore", str_op);
- return 0;
+ return;
}
tst_res(TINFO, "PID %d: fetched existing semaphore..id = %d", getpid(), id);
@@ -56,22 +56,16 @@ static int check_semaphore(LTP_ATTRIBUTE_UNUSED void *vtest)
tst_res(TPASS, "Plain cloned process found semaphore inside container");
else
tst_res(TFAIL, "%s: Container init process found semaphore", str_op);
-
- return 0;
}
static void run(void)
{
- clone_unshare_test(use_clone, CLONE_NEWIPC, check_semaphore, NULL);
+ clone_unshare_test(use_clone, CLONE_NEWIPC, check_semaphore);
}
static void setup(void)
{
use_clone = get_clone_unshare_enum(str_op);
-
- if (use_clone != T_NONE)
- check_newipc();
-
ipc_id = SAFE_SEMGET(MY_KEY, 1, IPC_CREAT | IPC_EXCL | 0666);
}
diff --git a/testcases/kernel/containers/sysvipc/semtest_2ns.c b/testcases/kernel/containers/sysvipc/semtest_2ns.c
index edff3f522..f03b18f72 100644
--- a/testcases/kernel/containers/sysvipc/semtest_2ns.c
+++ b/testcases/kernel/containers/sysvipc/semtest_2ns.c
@@ -40,7 +40,7 @@
static char *str_op;
static int use_clone;
-static int check_sem1(LTP_ATTRIBUTE_UNUSED void *vtest)
+static void check_sem1(void)
{
int id;
struct sembuf sm = {
@@ -62,11 +62,9 @@ static int check_sem1(LTP_ATTRIBUTE_UNUSED void *vtest)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
SAFE_SEMCTL(id, IPC_RMID, 0);
-
- return 0;
}
-static int check_sem2(LTP_ATTRIBUTE_UNUSED void *vtest)
+static void check_sem2(void)
{
int id;
struct sembuf sm = {
@@ -112,22 +110,17 @@ static int check_sem2(LTP_ATTRIBUTE_UNUSED void *vtest)
}
TST_CHECKPOINT_WAKE(0);
-
- return 0;
}
static void run(void)
{
- clone_unshare_test(use_clone, CLONE_NEWIPC, check_sem1, NULL);
- clone_unshare_test(use_clone, CLONE_NEWIPC, check_sem2, NULL);
+ clone_unshare_test(use_clone, CLONE_NEWIPC, check_sem1);
+ clone_unshare_test(use_clone, CLONE_NEWIPC, check_sem2);
}
static void setup(void)
{
use_clone = get_clone_unshare_enum(str_op);
-
- if (use_clone != T_NONE)
- check_newipc();
}
static void cleanup(void)
diff --git a/testcases/kernel/containers/sysvipc/shm_comm.c b/testcases/kernel/containers/sysvipc/shm_comm.c
index 12ad49110..e7ba8c8de 100644
--- a/testcases/kernel/containers/sysvipc/shm_comm.c
+++ b/testcases/kernel/containers/sysvipc/shm_comm.c
@@ -35,7 +35,7 @@
#define TESTKEY 124426L
#define SHMSIZE 50
-static int chld1_shm(LTP_ATTRIBUTE_UNUSED void *arg)
+static void chld1_shm(void)
{
int id;
char *shmem;
@@ -56,11 +56,9 @@ static int chld1_shm(LTP_ATTRIBUTE_UNUSED void *arg)
SAFE_SHMDT(shmem);
SAFE_SHMCTL(id, IPC_RMID, NULL);
-
- return 0;
}
-static int chld2_shm(LTP_ATTRIBUTE_UNUSED void *arg)
+static void chld2_shm(void)
{
int id;
char *shmem;
@@ -77,24 +75,17 @@ static int chld2_shm(LTP_ATTRIBUTE_UNUSED void *arg)
SAFE_SHMDT(shmem);
SAFE_SHMCTL(id, IPC_RMID, NULL);
-
- return 0;
}
static void run(void)
{
- clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld1_shm, NULL);
- clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld2_shm, NULL);
-}
-
-static void setup(void)
-{
- check_newipc();
+ clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld1_shm);
+ clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld2_shm);
}
static struct tst_test test = {
.test_all = run,
- .setup = setup,
.needs_root = 1,
.needs_checkpoints = 1,
+ .forks_child = 1,
};
diff --git a/testcases/kernel/containers/sysvipc/shmem_2nstest.c b/testcases/kernel/containers/sysvipc/shmem_2nstest.c
index ea3de94bd..a184cfcb4 100644
--- a/testcases/kernel/containers/sysvipc/shmem_2nstest.c
+++ b/testcases/kernel/containers/sysvipc/shmem_2nstest.c
@@ -40,7 +40,7 @@
static char *str_op;
static int use_clone;
-static int check_shmem1(LTP_ATTRIBUTE_UNUSED void *vtest)
+static void check_shmem1(void)
{
int id;
@@ -51,11 +51,9 @@ static int check_shmem1(LTP_ATTRIBUTE_UNUSED void *vtest)
TST_CHECKPOINT_WAKE_AND_WAIT(0);
SAFE_SHMCTL(id, IPC_RMID, NULL);
-
- return 0;
}
-static int check_shmem2(LTP_ATTRIBUTE_UNUSED void *vtest)
+static void check_shmem2(void)
{
TST_CHECKPOINT_WAIT(0);
@@ -74,22 +72,17 @@ static int check_shmem2(LTP_ATTRIBUTE_UNUSED void *vtest)
}
TST_CHECKPOINT_WAKE(0);
-
- return 0;
}
static void run(void)
{
- clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem1, NULL);
- clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem2, NULL);
+ clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem1);
+ clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem2);
}
static void setup(void)
{
use_clone = get_clone_unshare_enum(str_op);
-
- if (use_clone != T_NONE)
- check_newipc();
}
static struct tst_test test = {
diff --git a/testcases/kernel/containers/sysvipc/shmnstest.c b/testcases/kernel/containers/sysvipc/shmnstest.c
index d8ace723e..63ae62aa6 100644
--- a/testcases/kernel/containers/sysvipc/shmnstest.c
+++ b/testcases/kernel/containers/sysvipc/shmnstest.c
@@ -27,7 +27,7 @@ static char *str_op;
static int use_clone;
static int ipc_id = -1;
-static int check_shmid(LTP_ATTRIBUTE_UNUSED void *vtest)
+static void check_shmid(void)
{
TEST(shmget(TESTKEY, 100, 0));
if (TST_RET < 0) {
@@ -41,22 +41,16 @@ static int check_shmid(LTP_ATTRIBUTE_UNUSED void *vtest)
else
tst_res(TFAIL, "%s: child process found shmid", str_op);
}
-
- return 0;
}
static void run(void)
{
- clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmid, NULL);
+ clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmid);
}
static void setup(void)
{
use_clone = get_clone_unshare_enum(str_op);
-
- if (use_clone != T_NONE)
- check_newipc();
-
ipc_id = shmget(TESTKEY, 100, IPC_CREAT);
}
diff --git a/testcases/kernel/containers/userns/.gitignore b/testcases/kernel/containers/userns/.gitignore
new file mode 100644
index 000000000..dbd4aee27
--- /dev/null
+++ b/testcases/kernel/containers/userns/.gitignore
@@ -0,0 +1,9 @@
+userns01
+userns02
+userns03
+userns04
+userns05
+userns06_capcheck
+userns06
+userns07
+userns08
diff --git a/testcases/kernel/containers/userns/Makefile b/testcases/kernel/containers/userns/Makefile
index 80681096d..1531d1de6 100644
--- a/testcases/kernel/containers/userns/Makefile
+++ b/testcases/kernel/containers/userns/Makefile
@@ -1,26 +1,11 @@
-###############################################################################
-# ##
-# Copyright (c) Huawei Technologies Co., Ltd., 2015 ##
-# ##
-# 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. ##
-###############################################################################
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) Huawei Technologies Co., Ltd., 2015
+# Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
-LDLIBS := -lclone $(LDLIBS) $(CAP_LIBS)
+LDLIBS := $(LDLIBS) $(CAP_LIBS)
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/containers/userns/common.h b/testcases/kernel/containers/userns/common.h
index 635d0f190..9b3a47b69 100644
--- a/testcases/kernel/containers/userns/common.h
+++ b/testcases/kernel/containers/userns/common.h
@@ -8,35 +8,17 @@
#define COMMON_H
#include "tst_test.h"
-#include "lapi/sched.h"
#define UID_MAP 0
#define GID_MAP 1
-static int dummy_child(void *v)
-{
- (void)v;
- return 0;
-}
-
-static inline void check_newuser(void)
-{
- int pid, status;
-
- pid = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, dummy_child, NULL);
- if (pid == -1)
- tst_brk(TCONF | TTERRNO, "CLONE_NEWUSER not supported");
-
- SAFE_WAIT(&status);
-}
-
static inline void updatemap(int cpid, int type, int idnum, int parentmappid)
{
char path[BUFSIZ];
char content[BUFSIZ];
int fd;
- switch(type) {
+ switch (type) {
case UID_MAP:
sprintf(path, "/proc/%d/uid_map", cpid);
break;
diff --git a/testcases/kernel/containers/userns/userns01.c b/testcases/kernel/containers/userns/userns01.c
index 8ed7a9f41..6fe0cd637 100644
--- a/testcases/kernel/containers/userns/userns01.c
+++ b/testcases/kernel/containers/userns/userns01.c
@@ -20,9 +20,9 @@
#define _GNU_SOURCE
#include <stdio.h>
-#include "common.h"
#include "config.h"
#include <sys/capability.h>
+#include "lapi/sched.h"
#define OVERFLOWUIDPATH "/proc/sys/kernel/overflowuid"
#define OVERFLOWGIDPATH "/proc/sys/kernel/overflowgid"
@@ -30,10 +30,7 @@
static long overflowuid;
static long overflowgid;
-/*
- * child_fn1() - Inside a new user namespace
- */
-static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_fn1(void)
{
int uid, gid;
cap_t caps;
@@ -45,10 +42,8 @@ static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
tst_res(TINFO, "USERNS test is running in a new user namespace.");
- if (uid != overflowuid || gid != overflowgid)
- tst_res(TFAIL, "got unexpected uid=%d gid=%d", uid, gid);
- else
- tst_res(TPASS, "got expected uid and gid");
+ TST_EXP_EQ_LI(uid, overflowuid);
+ TST_EXP_EQ_LI(gid, overflowgid);
caps = cap_get_proc();
@@ -68,31 +63,32 @@ static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
tst_res(TFAIL, "unexpected effective/permitted caps at %d", i);
else
tst_res(TPASS, "expected capabilities");
-
- return 0;
}
static void setup(void)
{
- check_newuser();
-
SAFE_FILE_SCANF(OVERFLOWUIDPATH, "%ld", &overflowuid);
SAFE_FILE_SCANF(OVERFLOWGIDPATH, "%ld", &overflowgid);
}
static void run(void)
{
- int pid;
-
- pid = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, child_fn1, NULL);
- if (pid < 0)
- tst_brk(TBROK | TTERRNO, "clone failed");
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
+
+ if (!SAFE_CLONE(&args)) {
+ child_fn1();
+ return;
+ }
}
static struct tst_test test = {
.setup = setup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.caps = (struct tst_cap []) {
TST_CAP(TST_CAP_DROP, CAP_NET_RAW),
{}
diff --git a/testcases/kernel/containers/userns/userns02.c b/testcases/kernel/containers/userns/userns02.c
index dd784000e..3c8ce2133 100644
--- a/testcases/kernel/containers/userns/userns02.c
+++ b/testcases/kernel/containers/userns/userns02.c
@@ -14,13 +14,10 @@
#define _GNU_SOURCE
#include <stdio.h>
-#include "common.h"
#include "tst_test.h"
+#include "lapi/sched.h"
-/*
- * child_fn1() - Inside a new user namespace
- */
-static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_fn1(void)
{
int uid, gid;
@@ -29,29 +26,26 @@ static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
uid = geteuid();
gid = getegid();
- if (uid == 100 && gid == 100)
- tst_res(TPASS, "got expected uid and gid");
- else
- tst_res(TFAIL, "got unexpected uid=%d gid=%d", uid, gid);
-
- return 0;
-}
-
-static void setup(void)
-{
- check_newuser();
+ TST_EXP_EQ_LI(uid, 100);
+ TST_EXP_EQ_LI(gid, 100);
}
static void run(void)
{
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
int childpid;
int parentuid;
int parentgid;
char path[BUFSIZ];
- childpid = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, child_fn1, NULL);
- if (childpid < 0)
- tst_brk(TBROK | TTERRNO, "clone failed");
+ childpid = SAFE_CLONE(&args);
+ if (!childpid) {
+ child_fn1();
+ return;
+ }
parentuid = geteuid();
parentgid = getegid();
@@ -71,9 +65,9 @@ static void run(void)
}
static struct tst_test test = {
- .setup = setup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
.needs_kconfigs = (const char *[]) {
"CONFIG_USER_NS",
diff --git a/testcases/kernel/containers/userns/userns03.c b/testcases/kernel/containers/userns/userns03.c
index b90cc09ba..fca858702 100644
--- a/testcases/kernel/containers/userns/userns03.c
+++ b/testcases/kernel/containers/userns/userns03.c
@@ -32,8 +32,9 @@
#include <stdio.h>
#include <stdbool.h>
-#include "common.h"
#include "tst_test.h"
+#include "lapi/sched.h"
+#include "common.h"
#define CHILD1UID 0
#define CHILD1GID 0
@@ -42,23 +43,12 @@
#define UID_MAP 0
#define GID_MAP 1
-static int cpid1;
-static int parentuid;
-static int parentgid;
-
-/*
- * child_fn1() - Inside a new user namespace
- */
-static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_fn1(void)
{
TST_CHECKPOINT_WAIT(0);
- return 0;
}
-/*
- * child_fn2() - Inside a new user namespace
- */
-static int child_fn2(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_fn2(int cpid1, int parentuid, int parentgid)
{
int uid, gid;
char cpid1uidpath[BUFSIZ];
@@ -70,12 +60,8 @@ static int child_fn2(LTP_ATTRIBUTE_UNUSED void *arg)
uid = geteuid();
gid = getegid();
- tst_res(TINFO, "uid=%d, gid=%d", uid, gid);
-
- if (uid != CHILD2UID || gid != CHILD2GID)
- tst_res(TFAIL, "unexpected uid=%d gid=%d", uid, gid);
- else
- tst_res(TPASS, "expected uid and gid");
+ TST_EXP_EQ_LI(uid, CHILD2UID);
+ TST_EXP_EQ_LI(gid, CHILD2GID);
/* Get the uid parameters of the child_fn2 process */
SAFE_FILE_SCANF("/proc/self/uid_map", "%d %d %d", &idinsidens, &idoutsidens, &length);
@@ -127,32 +113,34 @@ static int child_fn2(LTP_ATTRIBUTE_UNUSED void *arg)
TST_CHECKPOINT_WAKE(0);
TST_CHECKPOINT_WAKE(1);
-
- return 0;
-}
-
-static void setup(void)
-{
- check_newuser();
}
static void run(void)
{
- pid_t cpid2;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
+ pid_t cpid1, cpid2;
+ uid_t parentuid;
+ gid_t parentgid;
char path[BUFSIZ];
int fd;
- int ret;
parentuid = geteuid();
parentgid = getegid();
- cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, child_fn1, NULL);
- if (cpid1 < 0)
- tst_brk(TBROK | TTERRNO, "cpid1 clone failed");
+ cpid1 = SAFE_CLONE(&args);
+ if (!cpid1) {
+ child_fn1();
+ return;
+ }
- cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, child_fn2, NULL);
- if (cpid2 < 0)
- tst_brk(TBROK | TTERRNO, "cpid2 clone failed");
+ cpid2 = SAFE_CLONE(&args);
+ if (!cpid2) {
+ child_fn2(cpid1, parentuid, parentgid);
+ return;
+ }
if (access("/proc/self/setgroups", F_OK) == 0) {
sprintf(path, "/proc/%d/setgroups", cpid1);
@@ -168,19 +156,12 @@ static void run(void)
* do so will fail with the error EPERM.)
*/
- /* test that setgroups can't be re-enabled */
- fd = SAFE_OPEN(path, O_WRONLY, 0644);
- ret = write(fd, "allow", 5);
-
- if (ret != -1)
- tst_brk(TBROK, "write action should fail");
- else if (errno != EPERM)
- tst_brk(TBROK | TTERRNO, "unexpected error");
+ tst_res(TINFO, "Check if setgroups can be re-enabled");
+ fd = SAFE_OPEN(path, O_WRONLY, 0644);
+ TST_EXP_FAIL2(write(fd, "allow", 5), EPERM);
SAFE_CLOSE(fd);
- tst_res(TPASS, "setgroups can't be re-enabled");
-
sprintf(path, "/proc/%d/setgroups", cpid2);
fd = SAFE_OPEN(path, O_WRONLY, 0644);
@@ -198,9 +179,9 @@ static void run(void)
}
static struct tst_test test = {
- .setup = setup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
.needs_kconfigs = (const char *[]) {
"CONFIG_USER_NS",
diff --git a/testcases/kernel/containers/userns/userns04.c b/testcases/kernel/containers/userns/userns04.c
index d8639502e..d20041f06 100644
--- a/testcases/kernel/containers/userns/userns04.c
+++ b/testcases/kernel/containers/userns/userns04.c
@@ -15,56 +15,49 @@
#define _GNU_SOURCE
#include <stdio.h>
-#include "common.h"
#include "tst_test.h"
-#include "lapi/syscalls.h"
+#include "lapi/sched.h"
-static void setup(void)
-{
- check_newuser();
- tst_syscall(__NR_setns, -1, 0);
-}
-
-static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
+static void child_fn1(void)
{
TST_CHECKPOINT_WAIT(0);
- return 0;
}
-static int child_fn2(void *arg)
+static void child_fn2(int fd)
{
- TEST(tst_syscall(__NR_setns, ((long)arg), CLONE_NEWUSER));
- if (TST_RET != -1 || TST_ERR != EPERM)
- tst_res(TFAIL | TERRNO, "child2 setns() error");
- else
- tst_res(TPASS, "child2 setns() failed as expected");
-
+ TST_EXP_FAIL(setns(fd, CLONE_NEWUSER), EPERM);
TST_CHECKPOINT_WAIT(1);
-
- return 0;
}
static void run(void)
{
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
pid_t cpid1, cpid2, cpid3;
char path[BUFSIZ];
int fd;
- cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL);
- if (cpid1 < 0)
- tst_brk(TBROK | TTERRNO, "clone failed");
+ cpid1 = SAFE_CLONE(&args);
+ if (!cpid1) {
+ child_fn1();
+ return;
+ }
sprintf(path, "/proc/%d/ns/user", cpid1);
fd = SAFE_OPEN(path, O_RDONLY, 0644);
- cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn2, (void *)((long)fd));
- if (cpid2 < 0)
- tst_brk(TBROK | TTERRNO, "clone failed");
- /* child 3 - throw-away process changing ns to child1 */
+ cpid2 = SAFE_CLONE(&args);
+ if (!cpid2) {
+ child_fn2(fd);
+ return;
+ }
+
cpid3 = SAFE_FORK();
if (!cpid3) {
- TST_EXP_PASS(tst_syscall(__NR_setns, fd, CLONE_NEWUSER));
+ TST_EXP_PASS(setns(fd, CLONE_NEWUSER));
return;
}
@@ -75,7 +68,6 @@ static void run(void)
}
static struct tst_test test = {
- .setup = setup,
.test_all = run,
.needs_root = 1,
.forks_child = 1,
diff --git a/testcases/kernel/containers/userns/userns05.c b/testcases/kernel/containers/userns/userns05.c
index 4c16694b1..e7a00af18 100644
--- a/testcases/kernel/containers/userns/userns05.c
+++ b/testcases/kernel/containers/userns/userns05.c
@@ -18,15 +18,12 @@
#include <stdio.h>
#include "tst_test.h"
+#include "lapi/sched.h"
#include "common.h"
-/*
- * child_fn1() - Inside a new user namespace
- */
-static int child_fn1(void)
+static void child_fn1(void)
{
TST_CHECKPOINT_WAIT(0);
- return 0;
}
static unsigned int getusernsidbypid(int pid)
@@ -47,14 +44,21 @@ static unsigned int getusernsidbypid(int pid)
static void run(void)
{
+ const struct tst_clone_args args1 = { .exit_signal = SIGCHLD };
+ const struct tst_clone_args args2 = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
int cpid1, cpid2, cpid3;
unsigned int parentuserns, cpid1userns, cpid2userns, newparentuserns;
parentuserns = getusernsidbypid(getpid());
- cpid1 = ltp_clone_quick(SIGCHLD, (void *)child_fn1, NULL);
- if (cpid1 < 0)
- tst_brk(TBROK | TTERRNO, "clone failed");
+ cpid1 = SAFE_CLONE(&args1);
+ if (!cpid1) {
+ child_fn1();
+ return;
+ }
cpid1userns = getusernsidbypid(cpid1);
@@ -64,23 +68,20 @@ static void run(void)
* CLONE_NEWUSER flag is a member of the same user namespace as its
* parent
*/
- if (parentuserns != cpid1userns)
- tst_res(TFAIL, "userns:parent should be equal to cpid1");
- else
- tst_res(TPASS, "userns:parent is equal to cpid1");
+ TST_EXP_EQ_LI(parentuserns, cpid1userns);
- cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL);
- if (cpid2 < 0)
- tst_brk(TBROK | TTERRNO, "clone failed");
+ cpid2 = SAFE_CLONE(&args2);
+ if (!cpid2) {
+ child_fn1();
+ return;
+ }
cpid2userns = getusernsidbypid(cpid2);
TST_CHECKPOINT_WAKE(0);
- if (parentuserns == cpid2userns)
- tst_res(TFAIL, "userns:parent should be not equal to cpid2");
- else
- tst_res(TPASS, "userns:parent is not equal to cpid2");
+ TST_EXP_EXPR(parentuserns != cpid2userns,
+ "parent namespace != child namespace");
cpid3 = SAFE_FORK();
if (!cpid3) {
@@ -91,20 +92,12 @@ static void run(void)
* is moved into a new user namespace which is not shared
* with any previously existing process
*/
- if (parentuserns == newparentuserns)
- tst_res(TFAIL, "unshared namespaces with same id");
- else
- tst_res(TPASS, "unshared namespaces with different id");
+ TST_EXP_EXPR(parentuserns != newparentuserns,
+ "parent namespace != unshared child namespace");
}
}
-static void setup(void)
-{
- check_newuser();
-}
-
static struct tst_test test = {
- .setup = setup,
.test_all = run,
.needs_root = 1,
.forks_child = 1,
diff --git a/testcases/kernel/containers/userns/userns06.c b/testcases/kernel/containers/userns/userns06.c
index 39f02e38a..a270dafdc 100644
--- a/testcases/kernel/containers/userns/userns06.c
+++ b/testcases/kernel/containers/userns/userns06.c
@@ -20,6 +20,7 @@
#define _GNU_SOURCE
#include <stdio.h>
+#include "lapi/sched.h"
#include "common.h"
#define TEST_APP "userns06_capcheck"
@@ -29,7 +30,7 @@
#define CHILD2UID 200
#define CHILD2GID 200
-static int child_fn1(void)
+static void child_fn1(void)
{
char *const args[] = { TEST_APP, "privileged", NULL };
int ret;
@@ -39,11 +40,9 @@ static int child_fn1(void)
ret = execv(args[0], args);
if (ret == -1)
tst_brk(TBROK | TERRNO, "execv: unexpected error");
-
- return 0;
}
-static int child_fn2(void)
+static void child_fn2(void)
{
int uid, gid, ret;
char *const args[] = { TEST_APP, "unprivileged", NULL };
@@ -53,27 +52,20 @@ static int child_fn2(void)
uid = geteuid();
gid = getegid();
- if (uid != CHILD2UID || gid != CHILD2GID) {
- tst_res(TFAIL, "unexpected uid=%d gid=%d", uid, gid);
- return 1;
- }
-
- tst_res(TPASS, "expected uid and gid");
+ TST_EXP_EQ_LI(uid, CHILD2UID);
+ TST_EXP_EQ_LI(gid, CHILD2GID);
ret = execv(args[0], args);
if (ret == -1)
tst_brk(TBROK | TERRNO, "execv: unexpected error");
-
- return 0;
-}
-
-static void setup(void)
-{
- check_newuser();
}
static void run(void)
{
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
pid_t cpid1;
pid_t cpid2;
int parentuid;
@@ -84,13 +76,17 @@ static void run(void)
parentuid = geteuid();
parentgid = getegid();
- cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL);
- if (cpid1 < 0)
- tst_brk(TBROK | TTERRNO, "cpid1 clone failed");
+ cpid1 = SAFE_CLONE(&args);
+ if (!cpid1) {
+ child_fn1();
+ return;
+ }
- cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn2, NULL);
- if (cpid2 < 0)
- tst_brk(TBROK | TTERRNO, "cpid2 clone failed");
+ cpid2 = SAFE_CLONE(&args);
+ if (!cpid2) {
+ child_fn2();
+ return;
+ }
if (access("/proc/self/setgroups", F_OK) == 0) {
sprintf(path, "/proc/%d/setgroups", cpid1);
@@ -117,9 +113,9 @@ static void run(void)
}
static struct tst_test test = {
- .setup = setup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
.resource_files = (const char *[]) {
TEST_APP,
diff --git a/testcases/kernel/containers/userns/userns06_capcheck.c b/testcases/kernel/containers/userns/userns06_capcheck.c
index c048ef63f..8669657b9 100644
--- a/testcases/kernel/containers/userns/userns06_capcheck.c
+++ b/testcases/kernel/containers/userns/userns06_capcheck.c
@@ -24,8 +24,8 @@ int main(int argc, char *argv[])
{
cap_t caps;
int i, last_cap;
- cap_flag_value_t flag_val;
- cap_flag_value_t expected_flag = 1;
+ cap_flag_value_t cap_flag;
+ cap_flag_value_t expected_cap_flag = 1;
tst_reinit();
@@ -35,24 +35,21 @@ int main(int argc, char *argv[])
SAFE_FILE_SCANF("/proc/sys/kernel/cap_last_cap", "%d", &last_cap);
if (strcmp("privileged", argv[1]))
- expected_flag = 0;
+ expected_cap_flag = 0;
caps = cap_get_proc();
for (i = 0; i <= last_cap; i++) {
- cap_get_flag(caps, i, CAP_EFFECTIVE, &flag_val);
- if (flag_val != expected_flag)
+ cap_get_flag(caps, i, CAP_EFFECTIVE, &cap_flag);
+ if (cap_flag != expected_cap_flag)
break;
- cap_get_flag(caps, i, CAP_PERMITTED, &flag_val);
- if (flag_val != expected_flag)
+ cap_get_flag(caps, i, CAP_PERMITTED, &cap_flag);
+ if (cap_flag != expected_cap_flag)
break;
}
- if (flag_val != expected_flag)
- tst_res(TFAIL, "unexpected effective/permitted caps at %d", i);
- else
- tst_res(TPASS, "expected caps at %d", i);
+ TST_EXP_EQ_LI(cap_flag, expected_cap_flag);
return 0;
}
diff --git a/testcases/kernel/containers/userns/userns07.c b/testcases/kernel/containers/userns/userns07.c
index 4659de636..2217a5ed0 100644
--- a/testcases/kernel/containers/userns/userns07.c
+++ b/testcases/kernel/containers/userns/userns07.c
@@ -16,19 +16,17 @@
#include <sys/wait.h>
#include "common.h"
#include "tst_test.h"
+#include "lapi/sched.h"
#define MAXNEST 32
-static void setup(void)
+static void child_fn1(const int level)
{
- check_newuser();
-}
-
-static int child_fn1(void *arg)
-{
- pid_t cpid1;
- long level = (long)arg;
- int status;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
+ pid_t cpid;
int parentuid;
int parentgid;
@@ -36,63 +34,68 @@ static int child_fn1(void *arg)
if (level == MAXNEST) {
tst_res(TPASS, "nested all children");
- return 0;
+ return;
}
- cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, (void *)(level + 1));
- if (cpid1 < 0) {
- tst_res(TFAIL | TERRNO, "level %ld, unexpected error", level);
- return 1;
+ cpid = SAFE_CLONE(&args);
+ if (!cpid) {
+ child_fn1(level + 1);
+ return;
}
parentuid = geteuid();
parentgid = getegid();
- updatemap(cpid1, UID_MAP, 0, parentuid);
- updatemap(cpid1, GID_MAP, 0, parentgid);
+ updatemap(cpid, UID_MAP, 0, parentuid);
+ updatemap(cpid, GID_MAP, 0, parentgid);
TST_CHECKPOINT_WAKE(0);
- SAFE_WAITPID(cpid1, &status, 0);
-
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
- tst_brk(TBROK, "child %s", tst_strstatus(status));
-
- return 0;
+ tst_reap_children();
}
static void run(void)
{
- pid_t cpid1;
+ const struct tst_clone_args args = {
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
+ };
+ pid_t cpid;
int parentuid;
int parentgid;
char path[BUFSIZ];
- cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, (void *)0);
- if (cpid1 < 0)
- tst_brk(TBROK | TTERRNO, "clone failed");
+ cpid = SAFE_CLONE(&args);
+ if (!cpid) {
+ child_fn1(0);
+ return;
+ }
parentuid = geteuid();
parentgid = getegid();
if (access("/proc/self/setgroups", F_OK) == 0) {
- sprintf(path, "/proc/%d/setgroups", cpid1);
+ sprintf(path, "/proc/%d/setgroups", cpid);
SAFE_FILE_PRINTF(path, "deny");
}
- updatemap(cpid1, UID_MAP, 0, parentuid);
- updatemap(cpid1, GID_MAP, 0, parentgid);
+ updatemap(cpid, UID_MAP, 0, parentuid);
+ updatemap(cpid, GID_MAP, 0, parentgid);
TST_CHECKPOINT_WAKE(0);
}
static struct tst_test test = {
- .setup = setup,
.test_all = run,
.needs_root = 1,
+ .forks_child = 1,
.needs_checkpoints = 1,
.needs_kconfigs = (const char *[]) {
"CONFIG_USER_NS",
NULL,
},
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/kernel/unprivileged_userns_clone", "1", TST_SR_SKIP},
+ {}
+ },
};
diff --git a/testcases/kernel/containers/userns/userns08.c b/testcases/kernel/containers/userns/userns08.c
index 2697d874b..72d7f8d12 100644
--- a/testcases/kernel/containers/userns/userns08.c
+++ b/testcases/kernel/containers/userns/userns08.c
@@ -31,8 +31,8 @@
static pid_t clone_newuser(void)
{
const struct tst_clone_args cargs = {
- CLONE_NEWUSER,
- SIGCHLD
+ .flags = CLONE_NEWUSER,
+ .exit_signal = SIGCHLD,
};
return SAFE_CLONE(&cargs);
@@ -136,6 +136,7 @@ static struct tst_test test = {
},
.save_restore = (const struct tst_path_val[]) {
{"/proc/sys/user/max_user_namespaces", NULL, TST_SR_SKIP},
+ {"/proc/sys/kernel/unprivileged_userns_clone", "1", TST_SR_SKIP},
{}
},
.tags = (const struct tst_tag[]) {
diff --git a/testcases/kernel/containers/userns/userns_helper.h b/testcases/kernel/containers/userns/userns_helper.h
deleted file mode 100644
index be47690ea..000000000
--- a/testcases/kernel/containers/userns/userns_helper.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd., 2015
- * 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.
- */
-
-#include "../libclone/libclone.h"
-#include "test.h"
-#include "safe_macros.h"
-#include <stdbool.h>
-
-#define UID_MAP 0
-#define GID_MAP 1
-
-static int dummy_child(void *v)
-{
- (void) v;
- return 0;
-}
-
-static int check_newuser(void)
-{
- int pid, status;
-
- pid = do_clone_unshare_test(T_CLONE, CLONE_NEWUSER, dummy_child, NULL);
- if (pid == -1)
- tst_brkm(TCONF | TERRNO, NULL, "CLONE_NEWUSER not supported");
- SAFE_WAIT(NULL, &status);
-
- return 0;
-}
-
-LTP_ATTRIBUTE_UNUSED static int updatemap(int cpid, bool type, int idnum,
- int parentmappid, void (*cleanup)(void))
-{
- char path[BUFSIZ];
- char content[BUFSIZ];
- int fd;
-
- if (type == UID_MAP)
- sprintf(path, "/proc/%d/uid_map", cpid);
- else if (type == GID_MAP)
- sprintf(path, "/proc/%d/gid_map", cpid);
- else
- tst_brkm(TBROK, cleanup, "invalid type parameter");
-
- sprintf(content, "%d %d 1", idnum, parentmappid);
- fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644);
- SAFE_WRITE(cleanup, SAFE_WRITE_ALL, fd, content, strlen(content));
- SAFE_CLOSE(cleanup, fd);
- return 0;
-}
diff --git a/testcases/kernel/containers/utsname/.gitignore b/testcases/kernel/containers/utsname/.gitignore
index 0e1f41dc8..945ed280e 100644
--- a/testcases/kernel/containers/utsname/.gitignore
+++ b/testcases/kernel/containers/utsname/.gitignore
@@ -1 +1,4 @@
-/utstest
+/utsname01
+/utsname02
+/utsname03
+/utsname04
diff --git a/testcases/kernel/containers/utsname/Makefile b/testcases/kernel/containers/utsname/Makefile
index 5efcbf648..b6beb8b8f 100644
--- a/testcases/kernel/containers/utsname/Makefile
+++ b/testcases/kernel/containers/utsname/Makefile
@@ -1,28 +1,7 @@
-################################################################################
-## ##
-## Copyright (c) International Business Machines Corp., 2007 ##
-## ##
-## 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, write to the Free Software ##
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ##
-## ##
-################################################################################
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2021 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-include $(abs_srcdir)/../Makefile.inc
-
-LDLIBS := -lclone -lpthread -lrt $(LDLIBS)
-
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/containers/utsname/runutstests_noltp.sh b/testcases/kernel/containers/utsname/runutstests_noltp.sh
deleted file mode 100755
index 43cb7e26b..000000000
--- a/testcases/kernel/containers/utsname/runutstests_noltp.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-################################################################################
-## ##
-## Copyright (c) International Business Machines Corp., 2007 ##
-## ##
-## 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, write to the Free Software ##
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ##
-## ##
-################################################################################
-
-oldhostname=`hostname`
-exit_code=0
-echo "unshare tests"
-for i in `seq 1 5`; do
- echo "test $i (unshare)"
- ./utstest_noltp unshare $i
- if [ $? -ne 0 ]; then
- exit_code=$?
- fi
-done
-echo "clone tests"
-for i in `seq 1 5`; do
- echo "test $i (clone)"
- ./utstest_noltp clone $i
- if [ $? -ne 0 ]; then
- exit_code=$?
- fi
-done
-hostname "$oldhostname"
-exit $exit_code
diff --git a/testcases/kernel/containers/utsname/utsname01.c b/testcases/kernel/containers/utsname/utsname01.c
new file mode 100644
index 000000000..fc5c1a271
--- /dev/null
+++ b/testcases/kernel/containers/utsname/utsname01.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Clone two plain processes and check if both read the same hostname.
+ */
+
+#define _GNU_SOURCE
+
+#include "tst_test.h"
+
+static char *hostname1;
+static char *hostname2;
+
+static void run(void)
+{
+ memset(hostname1, 0, HOST_NAME_MAX);
+ memset(hostname2, 0, HOST_NAME_MAX);
+
+ if (!SAFE_FORK()) {
+ SAFE_GETHOSTNAME(hostname1, HOST_NAME_MAX);
+ return;
+ }
+
+ if (!SAFE_FORK()) {
+ SAFE_GETHOSTNAME(hostname2, HOST_NAME_MAX);
+ return;
+ }
+
+ tst_reap_children();
+
+ TST_EXP_PASS(strcmp(hostname1, hostname2));
+}
+
+static void setup(void)
+{
+ hostname1 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ hostname2 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+static void cleanup(void)
+{
+ SAFE_MUNMAP(hostname1, HOST_NAME_MAX);
+ SAFE_MUNMAP(hostname2, HOST_NAME_MAX);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/containers/utsname/utsname02.c b/testcases/kernel/containers/utsname/utsname02.c
new file mode 100644
index 000000000..aa90596d4
--- /dev/null
+++ b/testcases/kernel/containers/utsname/utsname02.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Clone two plain processes, change hostname in the first one then check if
+ * hostaname has changed inside the second one as well.
+ */
+
+#define _GNU_SOURCE
+
+#include "tst_test.h"
+
+#define HOSTNAME "LTP_HOSTNAME"
+
+static char *hostname1;
+static char *hostname2;
+static char originalhost[HOST_NAME_MAX];
+
+static void reset_hostname(void)
+{
+ SAFE_SETHOSTNAME(originalhost, strlen(originalhost));
+}
+
+static void run(void)
+{
+ memset(hostname1, 0, HOST_NAME_MAX);
+ memset(hostname2, 0, HOST_NAME_MAX);
+
+ if (!SAFE_FORK()) {
+ SAFE_SETHOSTNAME(HOSTNAME, strlen(HOSTNAME));
+ SAFE_GETHOSTNAME(hostname1, HOST_NAME_MAX);
+
+ TST_CHECKPOINT_WAKE(0);
+ return;
+ }
+
+ if (!SAFE_FORK()) {
+ TST_CHECKPOINT_WAIT(0);
+
+ SAFE_GETHOSTNAME(hostname2, HOST_NAME_MAX);
+ return;
+ }
+
+ tst_reap_children();
+
+ TST_EXP_PASS(strcmp(hostname1, HOSTNAME));
+ TST_EXP_PASS(strcmp(hostname2, HOSTNAME));
+
+ reset_hostname();
+}
+
+static void setup(void)
+{
+ hostname1 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ hostname2 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+
+ memset(originalhost, 0, HOST_NAME_MAX);
+
+ SAFE_GETHOSTNAME(originalhost, HOST_NAME_MAX);
+}
+
+static void cleanup(void)
+{
+ SAFE_MUNMAP(hostname1, HOST_NAME_MAX);
+ SAFE_MUNMAP(hostname2, HOST_NAME_MAX);
+
+ reset_hostname();
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/containers/utsname/utsname03.c b/testcases/kernel/containers/utsname/utsname03.c
new file mode 100644
index 000000000..e5a4a56dc
--- /dev/null
+++ b/testcases/kernel/containers/utsname/utsname03.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2007
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Clone two processes using CLONE_NEWUTS, change hostname from the first
+ * container and check if hostname didn't change inside the second one.
+ */
+
+#define _GNU_SOURCE
+
+#include "tst_test.h"
+#include "lapi/sched.h"
+
+#define HOSTNAME "LTP_HOSTNAME"
+
+static char *str_op;
+static char *hostname1;
+static char *hostname2;
+static char originalhost[HOST_NAME_MAX];
+
+static void reset_hostname(void)
+{
+ SAFE_SETHOSTNAME(originalhost, strlen(originalhost));
+}
+
+static void child1_run(void)
+{
+ SAFE_SETHOSTNAME(HOSTNAME, strlen(HOSTNAME));
+ SAFE_GETHOSTNAME(hostname1, HOST_NAME_MAX);
+
+ TST_CHECKPOINT_WAKE(0);
+}
+
+static void child2_run(void)
+{
+ TST_CHECKPOINT_WAIT(0);
+
+ SAFE_GETHOSTNAME(hostname2, HOST_NAME_MAX);
+}
+
+static void run(void)
+{
+ const struct tst_clone_args cargs = {
+ .flags = CLONE_NEWUTS,
+ .exit_signal = SIGCHLD,
+ };
+
+ memset(hostname1, 0, HOST_NAME_MAX);
+ memset(hostname2, 0, HOST_NAME_MAX);
+
+ if (!str_op || !strcmp(str_op, "clone")) {
+ tst_res(TINFO, "clone() with CLONE_NEWUTS");
+
+ if (!SAFE_CLONE(&cargs)) {
+ child1_run();
+ return;
+ }
+
+ if (!SAFE_CLONE(&cargs)) {
+ child2_run();
+ return;
+ }
+ } else {
+ tst_res(TINFO, "unshare() with CLONE_NEWUTS");
+
+ if (!SAFE_FORK()) {
+ SAFE_UNSHARE(CLONE_NEWUTS);
+ child1_run();
+ return;
+ }
+
+ if (!SAFE_FORK()) {
+ SAFE_UNSHARE(CLONE_NEWUTS);
+ child2_run();
+ return;
+ }
+ }
+
+ tst_reap_children();
+
+ TST_EXP_PASS(strcmp(hostname1, HOSTNAME));
+ TST_EXP_PASS(strcmp(hostname2, originalhost));
+
+ reset_hostname();
+}
+
+static void setup(void)
+{
+ hostname1 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ hostname2 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+
+ memset(originalhost, 0, HOST_NAME_MAX);
+
+ SAFE_GETHOSTNAME(originalhost, HOST_NAME_MAX);
+}
+
+static void cleanup(void)
+{
+ SAFE_MUNMAP(hostname1, HOST_NAME_MAX);
+ SAFE_MUNMAP(hostname2, HOST_NAME_MAX);
+
+ reset_hostname();
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .options = (struct tst_option[]) {
+ { "m:", &str_op, "Test execution mode <clone|unshare>" },
+ {},
+ },
+};
diff --git a/testcases/kernel/containers/utsname/utsname04.c b/testcases/kernel/containers/utsname/utsname04.c
new file mode 100644
index 000000000..bf97880ba
--- /dev/null
+++ b/testcases/kernel/containers/utsname/utsname04.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Drop root privileges, create a container with CLONE_NEWUTS and verify that
+ * we receive a permission error.
+ */
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include "tst_test.h"
+#include "lapi/sched.h"
+
+static char *str_op;
+
+static void run(void)
+{
+ const struct tst_clone_args cargs = {
+ .flags = CLONE_NEWUTS,
+ .exit_signal = SIGCHLD,
+ };
+ struct passwd *pw;
+
+ tst_res(TINFO, "Dropping root privileges");
+
+ pw = SAFE_GETPWNAM("nobody");
+ SAFE_SETRESUID(pw->pw_uid, pw->pw_uid, pw->pw_uid);
+
+ if (!str_op || !strcmp(str_op, "clone")) {
+ TEST(tst_clone(&cargs));
+
+ if (TST_RET == -1)
+ tst_res(TPASS, "clone3() fails as expected");
+ else if (TST_RET == -2)
+ tst_res(TPASS, "clone() fails as expected");
+ else
+ tst_res(TFAIL, "tst_clone returns %ld", TST_RET);
+
+ TST_EXP_PASS(errno == EPERM);
+ } else {
+ if (!SAFE_FORK()) {
+ TST_EXP_EQ_LI(unshare(CLONE_NEWUTS), -1);
+ TST_EXP_PASS(errno == EPERM);
+ return;
+ }
+ }
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .options = (struct tst_option[]) {
+ { "m:", &str_op, "Test execution mode <clone|unshare>" },
+ {},
+ },
+};
diff --git a/testcases/kernel/containers/utsname/utstest.c b/testcases/kernel/containers/utsname/utstest.c
deleted file mode 100644
index 9ad19b6b2..000000000
--- a/testcases/kernel/containers/utsname/utstest.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
-* Copyright (c) International Business Machines Corp., 2007
-* 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, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************
- * Copyright 2007 IBM
- * Author: Serge Hallyn <serue@us.ibm.com>
- *
- * test1:
- P1: A=gethostname
- P2: B=gethostname
- Ensure(A==B)
-
- * test2:
- P1: sethostname(A);
- P2: (wait); B=gethostname
- Ensure (A==B)
-
- * test3:
- P1: A=gethostname; unshare(utsname); sethostname(newname); C=gethostname
- P2: B=gethostname; (wait); (wait); D=gethostname
- Ensure (A==B && A==D && C!=D)
-
- * test4:
- P1: A=gethostname; unshare(utsname); (wait); C=gethostname
- P2: B=gethostname; (wait); sethostname(newname); D=gethostname
- Ensure (A==B && A==C && C!=D)
-
- * test5:
- P1: drop_privs(); unshare(utsname); (wait); C=gethostname
- P2: (wait); sethostname(B); D=gethostname
- Ensure (B==C==D) and state is ok.
- *
- */
-
-#define _GNU_SOURCE 1
-#include <sys/wait.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "libclone.h"
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "uts_namespace";
-int TST_TOTAL = 1;
-
-static int dummy_child(void *v)
-{
- (void) v;
- return 0;
-}
-
-static void check_newuts(void)
-{
- int pid, status;
-
- pid = do_clone_unshare_test(T_CLONE, CLONE_NEWUTS, dummy_child, NULL);
- if (pid == -1)
- tst_brkm(TCONF | TERRNO, NULL, "CLONE_NEWUTS not supported");
-
- SAFE_WAIT(NULL, &status);
-}
-
-int drop_root(void)
-{
- int ret;
- ret = setresuid(1000, 1000, 1000);
- if (ret) {
- perror("setresuid");
- exit(4);
- }
- return 1;
-}
-
-#define HLEN 100
-#define NAME1 "serge1"
-#define NAME2 "serge2"
-
-int p1fd[2], p2fd[2];
-static char oldhost[HLEN];
-pid_t cpid;
-
-void picknewhostname(char *orig, char *new)
-{
- memset(new, 0, HLEN);
- if (strcmp(orig, NAME1) == 0)
- strcpy(new, NAME2);
- else
- strcpy(new, NAME1);
-}
-
-void zeroize(char *s)
-{
- memset(s, 0, HLEN);
-}
-
-char *tsttype;
-int P1(void *vtest)
-{
- char hostname[HLEN], newhostname[HLEN], rhostname[HLEN];
- int err;
- int len;
- int testnum;
-
- testnum = atoi((char *)vtest);
-
- close(p1fd[1]);
- close(p2fd[0]);
-
- switch (testnum) {
- case 1:
- gethostname(hostname, HLEN);
- zeroize(rhostname);
- len = read(p1fd[0], rhostname, HLEN);
- if (strcmp(hostname, rhostname) == 0) {
- tst_resm(TPASS, "test 1 (%s): success", tsttype);
- tst_exit();
- }
- tst_brkm(TFAIL, NULL,
- "test 1 (%s): hostname 1 %s, hostname 2 %s",
- tsttype, hostname, rhostname);
- case 2:
- gethostname(hostname, HLEN);
- picknewhostname(hostname, newhostname);
- err = sethostname(newhostname, strlen(newhostname));
- write(p2fd[1], "1", 1);
- if (err == -1) {
- tst_brkm(TFAIL, NULL,
- "test 2 (%s): failed to sethostname",
- tsttype);
- }
- zeroize(rhostname);
- len = read(p1fd[0], rhostname, HLEN);
- if (strcmp(newhostname, rhostname) == 0) {
- tst_resm(TPASS, "test 2 (%s): success", tsttype);
- tst_exit();
- }
- tst_brkm(TFAIL, NULL,
- "test 2 (%s) hostname 1 %s, hostname 2 %s",
- tsttype, newhostname, rhostname);
- case 3:
- gethostname(hostname, HLEN);
- picknewhostname(hostname, newhostname);
- err = sethostname(newhostname, strlen(newhostname));
- write(p2fd[1], "1", 1);
- if (err == -1) {
- tst_brkm(TFAIL, NULL,
- "test 3 (%s): failed to sethostname",
- tsttype);
- }
-
- zeroize(rhostname);
- len = read(p1fd[0], rhostname, HLEN);
- if (strcmp(newhostname, rhostname) == 0) {
- tst_brkm(TFAIL,
- NULL,
- "test 3 (%s): hostname 1 %s, hostname 2 %s, these should have been different",
- tsttype, newhostname, rhostname);
- }
- if (strcmp(hostname, rhostname) == 0) {
- tst_resm(TPASS, "test 3 (%s): success", tsttype);
- tst_exit();
- }
- tst_brkm(TFAIL,
- NULL,
- "test 3 (%s): hostname 1 %s, hostname 2 %s, should have been same",
- tsttype, hostname, rhostname);
-
- case 4:
- gethostname(hostname, HLEN);
- write(p2fd[1], "1", 1); /* tell p2 to go ahead and sethostname */
- zeroize(rhostname);
- len = read(p1fd[0], rhostname, HLEN);
- gethostname(newhostname, HLEN);
- if (strcmp(hostname, newhostname) != 0) {
- tst_brkm(TFAIL,
- NULL,
- "test 4 (%s): hostname 1 %s, hostname 2 %s, should be same",
- tsttype, hostname, newhostname);
- }
- if (strcmp(hostname, rhostname) == 0) {
- tst_brkm(TFAIL,
- NULL,
- "test 4 (%s): hostname 1 %s, hostname 2 %s, should be different",
- tsttype, hostname, rhostname);
- }
- tst_resm(TPASS, "test 4 (%s): successful", tsttype);
- tst_exit();
- case 5:
- write(p2fd[1], "1", 1); /* tell p2 to go ahead and sethostname */
- zeroize(rhostname);
- len = read(p1fd[0], rhostname, HLEN);
- gethostname(newhostname, HLEN);
- if (strcmp(rhostname, newhostname) != 0) {
- tst_brkm(TFAIL,
- NULL,
- "test 5 (%s): hostnames %s and %s should be same",
- tsttype, rhostname, newhostname);
- }
- tst_resm(TPASS, "test 5 (%s): successful", tsttype);
- tst_exit();
- default:
- break;
- }
- tst_exit();
-}
-
-int P2(void *vtest)
-{
- char hostname[HLEN], newhostname[HLEN];
- int len;
- int testnum;
-
- testnum = atoi((char *)vtest);
-
- close(p1fd[0]);
- close(p2fd[1]);
-
- switch (testnum) {
- case 1:
- gethostname(hostname, HLEN);
- write(p1fd[1], hostname, strlen(hostname));
- break;
- case 2:
- case 3:
- len = 0;
- while (!len) {
- len = read(p2fd[0], hostname, 1);
- }
- gethostname(hostname, HLEN);
- write(p1fd[1], hostname, strlen(hostname));
- break;
- case 4:
- case 5:
- len = 0;
- while (!len) {
- len = read(p2fd[0], hostname, 1);
- }
- if (hostname[0] == '0') {
- tst_resm(TPASS, "P2: P1 claims error");
- return 0;
- }
- gethostname(hostname, HLEN);
- picknewhostname(hostname, newhostname);
- sethostname(newhostname, strlen(newhostname));
- write(p1fd[1], newhostname, strlen(newhostname));
- break;
- default:
- tst_resm(TFAIL, "undefined test: %d", testnum);
- break;
- }
- return 0;
-}
-
-static void setup(void)
-{
- gethostname(oldhost, HLEN);
- tst_require_root();
- check_newuts();
-}
-
-static void cleanup(void)
-{
- sethostname(oldhost, strlen(oldhost));
-}
-
-#define UNSHARESTR "unshare"
-#define CLONESTR "clone"
-int main(int argc, char *argv[])
-{
- int r, pid, use_clone = T_UNSHARE;
- int testnum;
- void *vtest;
-
- setup();
- if (argc != 3) {
- tst_resm(TFAIL, "Usage: %s <clone|unshare> <testnum>",
- argv[0]);
- tst_resm(TFAIL,
- " where clone or unshare specifies unshare method,");
- tst_resm(TFAIL, " and testnum is between 1 and 5 inclusive");
- exit(2);
- }
- if (pipe(p1fd) == -1) {
- perror("pipe");
- exit(EXIT_FAILURE);
- }
- if (pipe(p2fd) == -1) {
- perror("pipe");
- exit(EXIT_FAILURE);
- }
-
- tsttype = UNSHARESTR;
- if (strcmp(argv[1], "clone") == 0) {
- use_clone = T_CLONE;
- tsttype = CLONESTR;
- }
-
- testnum = atoi(argv[2]);
-
- vtest = (void *)argv[2];
- switch (testnum) {
- case 1:
- case 2:
- r = do_clone_unshare_tests(T_NONE, 0, P1, vtest, P2, vtest);
- break;
- case 3:
- case 4:
- r = do_clone_unshare_tests(use_clone, CLONE_NEWUTS,
- P1, vtest, P2, vtest);
- break;
- case 5:
- pid = fork();
- if (pid == -1) {
- perror("fork");
- exit(2);
- }
- if (pid == 0) {
- if (!drop_root()) {
- tst_brkm(TFAIL, NULL, "failed to drop root.");
- }
- r = do_clone_unshare_test(use_clone, CLONE_NEWUTS,
- P1, vtest);
- write(p2fd[1], "0", 1); /* don't let p2 hang */
- exit(0);
- } else {
- P2(vtest);
- }
- break;
- default:
- tst_resm(TFAIL,
- "testnum should be between 1 and 5 inclusive.");
- break;
- }
-
- cleanup();
- tst_exit();
-}
diff --git a/testcases/kernel/controllers/cgroup/.gitignore b/testcases/kernel/controllers/cgroup/.gitignore
index 8deae77da..9f1d1ada9 100644
--- a/testcases/kernel/controllers/cgroup/.gitignore
+++ b/testcases/kernel/controllers/cgroup/.gitignore
@@ -2,3 +2,4 @@
/cgroup_regression_getdelays
/cgroup_core01
/cgroup_core02
+/cgroup_core03
diff --git a/testcases/kernel/controllers/cgroup/cgroup_core03.c b/testcases/kernel/controllers/cgroup/cgroup_core03.c
new file mode 100644
index 000000000..7d40d47f9
--- /dev/null
+++ b/testcases/kernel/controllers/cgroup/cgroup_core03.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2012 Christian Brauner <brauner-AT-kernel.org>
+ * Copyright (c) 2023 SUSE LLC <wegao@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test is copied from kselftest
+ * tools/testing/selftests/cgroup/test_kill.c.
+ *
+ * Only simple test implemented within current case, the other cases such
+ * as test_cgkill_tree and test_cgkill_forkbomb can be created later.
+ *
+ */
+
+#include <sys/wait.h>
+
+#include "lapi/syscalls.h"
+#include "tst_test.h"
+
+#define MAX_PID_NUM 100
+#define PID_NUM MIN(MAX_PID_NUM, (tst_ncpus_available() + 1))
+#define BUF_LEN (20 * PID_NUM)
+
+static int *data_ptr;
+static char *buf;
+static struct tst_cg_group *cg_child_test_simple;
+
+static int wait_for_pid(pid_t pid)
+{
+ int status, ret;
+
+again:
+ ret = waitpid(pid, &status, 0);
+ if (ret == -1) {
+ if (errno == EINTR)
+ goto again;
+
+ return -1;
+ }
+
+ if (WIFSIGNALED(status))
+ return 0;
+
+ return -1;
+}
+
+static int cg_run_nowait(const struct tst_cg_group *const cg)
+{
+ int pid;
+
+ pid = SAFE_FORK();
+ if (pid == 0) {
+ SAFE_CG_PRINTF(cg, "cgroup.procs", "%d", getpid());
+ if (tst_atomic_inc(data_ptr) == PID_NUM)
+ TST_CHECKPOINT_WAKE(0);
+ pause();
+ }
+
+ return pid;
+}
+
+static int cg_count_procs(const struct tst_cg_group *cg)
+{
+ char *ptr;
+
+ int nr = 0;
+
+ SAFE_CG_READ(cg, "cgroup.procs", buf, BUF_LEN);
+
+ for (ptr = buf; *ptr; ptr++)
+ if (*ptr == '\n')
+ nr++;
+
+ return nr;
+}
+
+static void run(void)
+{
+ pid_t pids[MAX_PID_NUM];
+ int i;
+ *data_ptr = 0;
+
+ cg_child_test_simple = tst_cg_group_mk(tst_cg, "cg_test_simple");
+
+ if (!SAFE_CG_HAS(cg_child_test_simple, "cgroup.kill")) {
+ cg_child_test_simple = tst_cg_group_rm(cg_child_test_simple);
+ tst_brk(TCONF, "cgroup.kill is not supported on your distribution");
+ }
+
+ memset(buf, 0, BUF_LEN);
+
+ for (i = 0; i < PID_NUM; i++)
+ pids[i] = cg_run_nowait(cg_child_test_simple);
+
+ TST_CHECKPOINT_WAIT(0);
+ TST_EXP_VAL(cg_count_procs(cg_child_test_simple), PID_NUM);
+ SAFE_CG_PRINTF(cg_child_test_simple, "cgroup.kill", "%d", 1);
+
+ for (i = 0; i < PID_NUM; i++)
+ TST_EXP_PASS_SILENT(wait_for_pid(pids[i]));
+
+ TST_EXP_VAL(cg_count_procs(cg_child_test_simple), 0);
+ cg_child_test_simple = tst_cg_group_rm(cg_child_test_simple);
+}
+
+static void setup(void)
+{
+ buf = tst_alloc(BUF_LEN);
+ data_ptr = SAFE_MMAP(NULL, sizeof(uintptr_t), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+static void cleanup(void)
+{
+ if (data_ptr)
+ SAFE_MUNMAP(data_ptr, sizeof(uintptr_t));
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .forks_child = 1,
+ .max_runtime = 20,
+ .needs_cgroup_ctrls = (const char *const []){ "base", NULL },
+ .needs_cgroup_ver = TST_CG_V2,
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/controllers/cgroup_fj/cgroup_fj_stress.sh b/testcases/kernel/controllers/cgroup_fj/cgroup_fj_stress.sh
index d80b83bbd..72d3c53f4 100755
--- a/testcases/kernel/controllers/cgroup_fj/cgroup_fj_stress.sh
+++ b/testcases/kernel/controllers/cgroup_fj/cgroup_fj_stress.sh
@@ -7,7 +7,7 @@
TCID="cgroup_fj_stress"
TST_CNT=1
-TST_TESTFUNC=test
+TST_TESTFUNC=do_test
TST_SETUP=setup
TST_CLEANUP=cleanup
TST_POS_ARGS=4
@@ -126,7 +126,7 @@ cleanup()
common_cleanup
}
-test()
+do_test()
{
tst_res TINFO "Creating subgroups ..."
diff --git a/testcases/kernel/controllers/cpuctl/run_cpuctl_stress_test.sh b/testcases/kernel/controllers/cpuctl/run_cpuctl_stress_test.sh
index 3fcba1491..5b53544cf 100755
--- a/testcases/kernel/controllers/cpuctl/run_cpuctl_stress_test.sh
+++ b/testcases/kernel/controllers/cpuctl/run_cpuctl_stress_test.sh
@@ -200,7 +200,7 @@ usage ()
cleanup;
exit -1;
else
- echo "Succesfully launched def task $! too";
+ echo "Successfully launched def task $! too";
fi
;;
"9" )
@@ -279,7 +279,7 @@ usage ()
cleanup;
exit -1;
else
- echo "Succesfully launched def task $! too";
+ echo "Successfully launched def task $! too";
fi
;;
"10" )
@@ -346,7 +346,7 @@ usage ()
cleanup;
exit -1;
else
- echo "Succesfully launched def task $! too";
+ echo "Successfully launched def task $! too";
fi
;;
* )
diff --git a/testcases/kernel/controllers/cpuctl/run_cpuctl_test.sh b/testcases/kernel/controllers/cpuctl/run_cpuctl_test.sh
index bbbd2fbcb..5b09fb273 100755
--- a/testcases/kernel/controllers/cpuctl/run_cpuctl_test.sh
+++ b/testcases/kernel/controllers/cpuctl/run_cpuctl_test.sh
@@ -144,7 +144,7 @@ NUM_CPUS=`tst_ncpus`
cleanup;
exit -1;
else
- echo "Succesfully launched def task $! too";
+ echo "Successfully launched def task $! too";
fi
;;
"4" )
@@ -210,7 +210,7 @@ NUM_CPUS=`tst_ncpus`
cleanup;
exit -1;
else
- echo "Succesfully launched def task $! too";
+ echo "Successfully launched def task $! too";
fi
;;
"5" )
@@ -270,7 +270,7 @@ NUM_CPUS=`tst_ncpus`
cleanup;
exit -1;
else
- echo "Succesfully launched def task $! too";
+ echo "Successfully launched def task $! too";
fi
;;
diff --git a/testcases/kernel/controllers/cpuctl_fj/run_cpuctl_test_fj.sh b/testcases/kernel/controllers/cpuctl_fj/run_cpuctl_test_fj.sh
index ab73c801b..5cb6bb566 100755
--- a/testcases/kernel/controllers/cpuctl_fj/run_cpuctl_test_fj.sh
+++ b/testcases/kernel/controllers/cpuctl_fj/run_cpuctl_test_fj.sh
@@ -63,7 +63,7 @@ cleanup()
return 0
}
- find $CPUCTL -type d | sort | sed -n '2,$p' | tac | while read tmpdir
+ find $CPUCTL -type d | sort | sed -n '2,$p' | tac | while read -r tmpdir
do
while read tmppid
do
diff --git a/testcases/kernel/controllers/cpuset/cpuset_funcs.sh b/testcases/kernel/controllers/cpuset/cpuset_funcs.sh
index 87ba7da1f..0cfa0c17e 100755
--- a/testcases/kernel/controllers/cpuset/cpuset_funcs.sh
+++ b/testcases/kernel/controllers/cpuset/cpuset_funcs.sh
@@ -184,7 +184,7 @@ cleanup()
echo $CHILDREN_VALUE > $CLONE_CHILDREN
echo $SCHED_LB_VALUE > $SCHED_LB
- find "$CPUSET" -type d | sort | sed -n '2,$p' | tac | while read subdir
+ find "$CPUSET" -type d | sort | sed -n '2,$p' | tac | while read -r subdir
do
while read pid
do
diff --git a/testcases/kernel/controllers/cpuset/cpuset_memory_pressure_test/cpuset_memory_pressure_testset.sh b/testcases/kernel/controllers/cpuset/cpuset_memory_pressure_test/cpuset_memory_pressure_testset.sh
index eddd7f6c5..fff0ab318 100755
--- a/testcases/kernel/controllers/cpuset/cpuset_memory_pressure_test/cpuset_memory_pressure_testset.sh
+++ b/testcases/kernel/controllers/cpuset/cpuset_memory_pressure_test/cpuset_memory_pressure_testset.sh
@@ -33,10 +33,12 @@ check
exit_status=0
# usable physical memory
-py_mem=$(free -m | awk '{if(NR==2) print $4 + $6 + $7}')
+py_mem=$(awk '/MemAvailable/ {print $2}' /proc/meminfo)
+py_mem=$(( $py_mem / 1024 ))
# free swap space
-sw_mem=$(free -m | awk '{if(NR==4) print $4}')
+sw_mem=$(awk '/SwapFree/ {print $2}' /proc/meminfo)
+sw_mem=$(( $sw_mem / 1024 ))
# the memory which is going to be used
usemem=$((py_mem - 20))
diff --git a/testcases/kernel/controllers/cpuset/cpuset_memory_spread_test/cpuset_memory_spread_testset.sh b/testcases/kernel/controllers/cpuset/cpuset_memory_spread_test/cpuset_memory_spread_testset.sh
index e2767ef05..f7230a4ea 100755
--- a/testcases/kernel/controllers/cpuset/cpuset_memory_spread_test/cpuset_memory_spread_testset.sh
+++ b/testcases/kernel/controllers/cpuset/cpuset_memory_spread_test/cpuset_memory_spread_testset.sh
@@ -38,7 +38,15 @@ nr_mems=$N_NODES
# on which it is running. The other nodes' slab space has littler change.(less
# than 1000 kb).
upperlimit=10000
-lowerlimit=2000
+
+# set lowerlimit according to pagesize
+# pagesize(bytes) | lowerlimit(kb)
+# ------------------------------------
+# 4096 | 2048
+# 16384 | 8192
+
+PAGE_SIZE=`tst_getconf PAGESIZE`
+lowerlimit=$((PAGE_SIZE * 512 / 1024))
cpus_all="$(seq -s, 0 $((nr_cpus-1)))"
mems_all="$(seq -s, 0 $((nr_mems-1)))"
diff --git a/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_testset.sh b/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_testset.sh
index cb7dbd867..c1e7cea8f 100755
--- a/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_testset.sh
+++ b/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_testset.sh
@@ -41,7 +41,7 @@ mems_all="$(seq -s, 0 $((nr_mems-1)))"
cpu_of_node0=0
HUGEPAGESIZE=$(awk '/Hugepagesize/{ print $2 }' /proc/meminfo)
-HUGEPAGESIZE=$(($HUGEPAGESIZE * 1024))
+HUGEPAGESIZE=$((${HUGEPAGESIZE:-0} * 1024))
MEMORY_RESULT="$CPUSET_TMP/memory_result"
diff --git a/testcases/kernel/controllers/cpuset/cpuset_regression_test.sh b/testcases/kernel/controllers/cpuset/cpuset_regression_test.sh
index 8e87d20e4..a5757309f 100755
--- a/testcases/kernel/controllers/cpuset/cpuset_regression_test.sh
+++ b/testcases/kernel/controllers/cpuset/cpuset_regression_test.sh
@@ -12,7 +12,7 @@
TST_SETUP=setup
TST_CLEANUP=cleanup
-TST_TESTFUNC=test
+TST_TESTFUNC=do_test
TST_NEEDS_ROOT=1
TST_NEEDS_TMPDIR=1
TST_MIN_KVER="3.18"
@@ -130,6 +130,11 @@ setup()
tst_res TINFO "test starts with cgroup version $cgroup_version"
+ if [ "$cgroup_version" = "2" ]; then
+ tst_brk TCONF "cgroup v2 found, skipping test"
+ return
+ fi
+
if ! [ -f ${root_cpuset_dir}/${cpu_exclusive} ]; then
cpu_exclusive=cpu_exclusive
cpus=cpus
@@ -178,7 +183,7 @@ cleanup()
cgroup_cleanup
}
-test()
+do_test()
{
local cpu_exclusive_tmp cpus_value
diff --git a/testcases/kernel/controllers/freezer/00_description.txt b/testcases/kernel/controllers/freezer/00_description.txt
index b59741282..989a4a405 100644
--- a/testcases/kernel/controllers/freezer/00_description.txt
+++ b/testcases/kernel/controllers/freezer/00_description.txt
@@ -21,7 +21,7 @@ freeze_self_thaw.sh
The subshell process sleeps and then freezes the control group it is a
part of. We then thaw the subshell process. We expect the unthawed
subshell process to need cleanup afterwards (allows us to test
- successfull thawing).
+ successful thawing).
freeze_sleep_thaw.sh
This bash script tests freezer code by starting a long sleep process.
diff --git a/testcases/kernel/controllers/freezer/freeze_self_thaw.sh b/testcases/kernel/controllers/freezer/freeze_self_thaw.sh
index 773c4afa1..f6943cda8 100755
--- a/testcases/kernel/controllers/freezer/freeze_self_thaw.sh
+++ b/testcases/kernel/controllers/freezer/freeze_self_thaw.sh
@@ -22,7 +22,7 @@
# This bash script tests freezer code by starting a long subshell process.
# The subshell process sleeps and then freezes the control group it is a
# part of. We then thaw the subshell process. We expect the unthawed subshell
-# process to need cleanup afterwards (allows us to test successfull thawing).
+# process to need cleanup afterwards (allows us to test successful thawing).
#
. "${CGROUPS_TESTROOT}/libcgroup_freezer"
diff --git a/testcases/kernel/controllers/freezer/vfork_freeze.sh b/testcases/kernel/controllers/freezer/vfork_freeze.sh
index 4bb844ff4..6d3487600 100755
--- a/testcases/kernel/controllers/freezer/vfork_freeze.sh
+++ b/testcases/kernel/controllers/freezer/vfork_freeze.sh
@@ -60,7 +60,7 @@ TMPLOG="$TMPDIR/${0##*/}.$$.txt"
# create new processes. The vfork'ed processes then sleep, causing the
# parent process ($sample_proc) to enter the TASK_UNINTERRUPTIBLE state
# for the duration of the sleep.
-function vfork_sleep()
+vfork_sleep()
{
vfork -s$sample_sleep 1 -f "$TMPLOG" &
local rc=$?
diff --git a/testcases/kernel/controllers/io/io_control01.c b/testcases/kernel/controllers/io/io_control01.c
index c4e171af5..691196886 100644
--- a/testcases/kernel/controllers/io/io_control01.c
+++ b/testcases/kernel/controllers/io/io_control01.c
@@ -55,6 +55,7 @@ static void run(void)
char *buf = SAFE_MALLOC(MAX((size_t)BUFSIZ, pgsz));
struct io_stats start;
+ memset(&start, 0, sizeof(struct io_stats));
SAFE_CG_READ(tst_cg, "io.stat", buf, BUFSIZ - 1);
line = strtok_r(buf, "\n", &buf_ptr);
while (line) {
diff --git a/testcases/kernel/controllers/memcg/functional/memcg_failcnt.sh b/testcases/kernel/controllers/memcg/functional/memcg_failcnt.sh
index 1be98a056..3a02d16c2 100755
--- a/testcases/kernel/controllers/memcg/functional/memcg_failcnt.sh
+++ b/testcases/kernel/controllers/memcg/functional/memcg_failcnt.sh
@@ -8,11 +8,11 @@
# Restructure for LTP: Shi Weihua <shiwh@cn.fujitsu.com>
# Added memcg enable/disable functionality: Rishikesh K Rajak <risrajak@linux.vnet.ibm.com>
-MEMCG_TESTFUNC=test
+MEMCG_TESTFUNC=do_test
MEMCG_SHMMAX=1
TST_TEST_DATA="--mmap-anon --mmap-file --shm"
-test()
+do_test()
{
ROD echo $MEMORY_LIMIT \> memory.limit_in_bytes
diff --git a/testcases/kernel/controllers/memcg/functional/memcg_lib.sh b/testcases/kernel/controllers/memcg/functional/memcg_lib.sh
index dbb61e6b1..5efede9cf 100755
--- a/testcases/kernel/controllers/memcg/functional/memcg_lib.sh
+++ b/testcases/kernel/controllers/memcg/functional/memcg_lib.sh
@@ -404,8 +404,8 @@ fi
# Post 4.16 kernel updates stat in batch (> 32 pages) every time
# Post 6.1 kernel updates stat in batch (> 64 pages) every time
# 1813e51eece0ad6 ("memcg: increase MEMCG_CHARGE_BATCH to 64")
-# has been merged since 5.14.0-191.el9.
-if tst_kvcmp -lt "6.1 RHEL9:5.14.0-191" ; then
+# has been merged since 5.14.0-191.el9 and 4.18.0-438.el8.
+if tst_kvcmp -lt "6.1 RHEL9:5.14.0-191 RHEL8:4.18.0-438" ; then
PAGESIZES=$(($PAGESIZE * 33))
else
PAGESIZES=$(($PAGESIZE * 65))
diff --git a/testcases/kernel/controllers/memcg/stress/memcg_stress_test.sh b/testcases/kernel/controllers/memcg/stress/memcg_stress_test.sh
index cb52840d7..47cac9af8 100755
--- a/testcases/kernel/controllers/memcg/stress/memcg_stress_test.sh
+++ b/testcases/kernel/controllers/memcg/stress/memcg_stress_test.sh
@@ -33,14 +33,17 @@ setup()
echo 3 > /proc/sys/vm/drop_caches
sleep 2
- local mem_free=`cat /proc/meminfo | grep MemFree | awk '{ print $2 }'`
- local swap_free=`cat /proc/meminfo | grep SwapFree | awk '{ print $2 }'`
- local pgsize=`tst_getconf PAGESIZE`
-
- MEM=$(( $mem_free + $swap_free / 2 ))
+ local mem_free=$(awk '/MemFree/ {print $2}' /proc/meminfo)
+ local mem_available=$(awk '/MemAvailable/ {print $2}' /proc/meminfo)
+ local swap_free=$(awk '/SwapFree/ {print $2}' /proc/meminfo)
+ local mem_min=$(cat /proc/sys/vm/min_free_kbytes)
+
+ mem_min=$(( $mem_min + $mem_min/10 ))
+ [ $swap_free -gt $mem_min ] && RESERVED_MEM=0 || RESERVED_MEM=$mem_min
+ [ $mem_free -lt $mem_available ] && MEM=$mem_free || MEM=$mem_available
+ MEM=$(( $MEM - $RESERVED_MEM ))
MEM=$(( $MEM / 1024 ))
RUN_TIME=$(( 15 * 60 ))
- [ "$pgsize" = "4096" ] && THREAD_SPARE_MB=1 || THREAD_SPARE_MB=8
tst_res TINFO "Calculated available memory $MEM MB"
}
@@ -93,12 +96,12 @@ run_stress()
test1()
{
- run_stress 150 $(( ($MEM - 150 * $THREAD_SPARE_MB) / 150 )) 5 $RUN_TIME
+ run_stress 150 $(( $MEM / 150 )) 5 $RUN_TIME
}
test2()
{
- run_stress 1 $(( $MEM - $THREAD_SPARE_MB)) 5 $RUN_TIME
+ run_stress 1 $MEM 5 $RUN_TIME
}
. cgroup_lib.sh
diff --git a/testcases/kernel/crypto/pcrypt_aead01.c b/testcases/kernel/crypto/pcrypt_aead01.c
index 5eefee4cb..3b4f5d8d1 100644
--- a/testcases/kernel/crypto/pcrypt_aead01.c
+++ b/testcases/kernel/crypto/pcrypt_aead01.c
@@ -7,7 +7,7 @@
* Originally found by syzkaller:
* https://groups.google.com/forum/#!topic/syzkaller-bugs/NKn_ivoPOpk
*
- * Test for CVE-2017-5754 - pcrypt mishandles freeing instances.
+ * Test for CVE-2017-18075 - pcrypt mishandles freeing instances.
*
* The test works by adding and then removing pcrypt-AEAD instances.
* See commit d76c68109f37 crypto: pcrypt - fix freeing pcrypt instances.
@@ -78,7 +78,7 @@ static struct tst_test test = {
.max_runtime = 300,
.tags = (const struct tst_tag[]) {
{"linux-git", "d76c68109f37"},
- {"CVE", "2017-5754"},
+ {"CVE", "2017-18075"},
{}
}
};
diff --git a/testcases/kernel/device-drivers/nls/README b/testcases/kernel/device-drivers/nls/README
index 67c1d8f0c..1de4ec442 100644
--- a/testcases/kernel/device-drivers/nls/README
+++ b/testcases/kernel/device-drivers/nls/README
@@ -11,7 +11,7 @@ Before loading nlsTest.ko the nls_base.ko module must already be loaded.
Building
--------
-To build nlsTest.ko you will need to have the the Linux kernel sources installed
+To build nlsTest.ko you will need to have the Linux kernel sources installed
on your build environment. Execute "make" from the current directory should
build the nlsTest.ko.
diff --git a/testcases/kernel/device-drivers/zram/zram01.sh b/testcases/kernel/device-drivers/zram/zram01.sh
index 58d233f91..6bc305f2c 100755
--- a/testcases/kernel/device-drivers/zram/zram01.sh
+++ b/testcases/kernel/device-drivers/zram/zram01.sh
@@ -105,6 +105,26 @@ zram_mount()
tst_res TPASS "mount of zram device(s) succeeded"
}
+read_mem_used_total()
+{
+ echo $(awk '{print $3}' $1)
+}
+
+# Reads /sys/block/zram*/mm_stat until mem_used_total is not 0.
+check_read_mem_used_total()
+{
+ local file="$1"
+ local mem_used_total
+
+ tst_res TINFO "$file"
+ cat $file >&2
+
+ mem_used_total=$(read_mem_used_total $file)
+ [ "$mem_used_total" -eq 0 ] && return 1
+
+ return 0
+}
+
zram_fill_fs()
{
local mem_used_total
@@ -133,9 +153,12 @@ zram_fill_fs()
continue
fi
- mem_used_total=`awk '{print $3}' "/sys/block/zram$i/mm_stat"`
+ TST_RETRY_FUNC "check_read_mem_used_total /sys/block/zram$i/mm_stat" 0
+ mem_used_total=$(read_mem_used_total /sys/block/zram$i/mm_stat)
+ tst_res TINFO "mem_used_total: $mem_used_total"
+
v=$((100 * 1024 * $b / $mem_used_total))
- r=`echo "scale=2; $v / 100 " | bc`
+ r=$(echo "scale=2; $v / 100 " | bc)
if [ "$v" -lt 100 ]; then
tst_res TFAIL "compression ratio: $r:1"
diff --git a/testcases/kernel/fs/doio/write_log.c b/testcases/kernel/fs/doio/write_log.c
index e8ef9c7cb..c06677fc6 100644
--- a/testcases/kernel/fs/doio/write_log.c
+++ b/testcases/kernel/fs/doio/write_log.c
@@ -87,7 +87,7 @@
/*#define PATH_MAX pathconf("/", _PC_PATH_MAX)*/
#endif
-char Wlog_Error_String[256];
+char Wlog_Error_String[2048];
#if __STDC__
static int wlog_rec_pack(struct wlog_rec *wrec, char *buf, int flag);
@@ -129,7 +129,7 @@ int wlog_open(struct wlog_file *wfile, int trunc, int mode)
umask(omask);
if (wfile->w_afd == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not open write_log - open(%s, %#o, %#o) failed: %s\n",
wfile->w_file, oflags, mode, strerror(errno));
return -1;
@@ -141,7 +141,7 @@ int wlog_open(struct wlog_file *wfile, int trunc, int mode)
oflags = O_RDWR;
if ((wfile->w_rfd = open(wfile->w_file, oflags)) == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not open write log - open(%s, %#o) failed: %s\n",
wfile->w_file, oflags, strerror(errno));
close(wfile->w_afd);
@@ -218,14 +218,14 @@ int wlog_record_write(struct wlog_file *wfile, struct wlog_rec *wrec,
reclen += 2;
if (write(wfile->w_afd, wbuf, reclen) == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not write log - write(%s, %s, %d) failed: %s\n",
wfile->w_file, wbuf, reclen, strerror(errno));
return -1;
} else {
offset = lseek(wfile->w_afd, 0, SEEK_CUR) - reclen;
if (offset == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not reposition file pointer - lseek(%s, 0, SEEK_CUR) failed: %s\n",
wfile->w_file, strerror(errno));
return -1;
@@ -233,13 +233,13 @@ int wlog_record_write(struct wlog_file *wfile, struct wlog_rec *wrec,
}
} else {
if ((lseek(wfile->w_rfd, offset, SEEK_SET)) == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not reposition file pointer - lseek(%s, %ld, SEEK_SET) failed: %s\n",
wfile->w_file, offset, strerror(errno));
return -1;
} else {
if ((write(wfile->w_rfd, wbuf, reclen)) == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not write log - write(%s, %s, %d) failed: %s\n",
wfile->w_file, wbuf, reclen,
strerror(errno));
@@ -274,14 +274,14 @@ int wlog_scan_backward(struct wlog_file *wfile, int nrecs,
*/
if ((lseek(fd, 0, SEEK_END)) == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not reposition file pointer - lseek(%s, 0, SEEK_END) failed: %s\n",
wfile->w_file, strerror(errno));
return -1;
}
offset = lseek(fd, 0, SEEK_CUR);
if ((offset == -1)) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not reposition file pointer - lseek(%s, 0, SEEK_CUR) failed: %s\n",
wfile->w_file, strerror(errno));
return -1;
@@ -309,7 +309,7 @@ int wlog_scan_backward(struct wlog_file *wfile, int nrecs,
* Move to the proper file offset, and read into buf
*/
if ((lseek(fd, offset, SEEK_SET)) == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not reposition file pointer - lseek(%s, %d, SEEK_SET) failed: %s\n",
wfile->w_file, offset, strerror(errno));
return -1;
@@ -318,7 +318,7 @@ int wlog_scan_backward(struct wlog_file *wfile, int nrecs,
nbytes = read(fd, bufstart, bufend - bufstart - leftover);
if (nbytes == -1) {
- sprintf(Wlog_Error_String,
+ snprintf(Wlog_Error_String, sizeof(Wlog_Error_String),
"Could not read history file at offset %d - read(%d, %p, %d) failed: %s\n",
offset, fd, bufstart,
(int)(bufend - bufstart - leftover),
diff --git a/testcases/kernel/fs/fs_bind/fs_bind_lib.sh b/testcases/kernel/fs/fs_bind/fs_bind_lib.sh
index 2dd9ef08f..52190a7ca 100644
--- a/testcases/kernel/fs/fs_bind/fs_bind_lib.sh
+++ b/testcases/kernel/fs/fs_bind/fs_bind_lib.sh
@@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) International Business Machines Corp., 2005
# Copyright (c) 2021 Joerg Vehlow <joerg.vehlow@aox-tech.de>
+# Copyright (c) Linux Test Project, 2022-2023
# Based on work by: Avantika Mathur (mathurav@us.ibm.com)
TST_NEEDS_TMPDIR=1
@@ -109,7 +110,7 @@ fs_bind_check()
fi
if [ $use_ns -eq 1 ]; then
- output="$(ns_exec ${FS_BIND_MNTNS_PID} mnt diff -r "$PWD/$dir1" "$PWD/$dir2" 2> /dev/null)"
+ output="$(tst_ns_exec ${FS_BIND_MNTNS_PID} mnt diff -r "$PWD/$dir1" "$PWD/$dir2" 2> /dev/null)"
else
output="$(diff -r "$dir1" "$dir2" 2> /dev/null)"
fi
@@ -197,13 +198,13 @@ _fs_bind_setup_test()
fs_bind_create_ns()
{
[ -n "$FS_BIND_MNTNS_PID" ] && tst_brk TBROK "Namespace exist already"
- FS_BIND_MNTNS_PID=$(ns_create mnt)
+ FS_BIND_MNTNS_PID=$(tst_ns_create mnt)
}
fs_bind_exec_ns()
{
[ -z "$FS_BIND_MNTNS_PID" ] && tst_brk TBROK "Namespace does not exist"
- EXPECT_PASS ns_exec $FS_BIND_MNTNS_PID mnt "$@"
+ EXPECT_PASS tst_ns_exec $FS_BIND_MNTNS_PID mnt "$@"
}
fs_bind_destroy_ns()
diff --git a/testcases/kernel/fs/fs_fill/fs_fill.c b/testcases/kernel/fs/fs_fill/fs_fill.c
index 2027b6df1..2ecd8e2ad 100644
--- a/testcases/kernel/fs/fs_fill/fs_fill.c
+++ b/testcases/kernel/fs/fs_fill/fs_fill.c
@@ -18,6 +18,7 @@
#include "tst_test.h"
#define MNTPOINT "mntpoint"
+#define THREADS_DIR MNTPOINT "/subdir"
static volatile int run;
static unsigned int nthreads;
@@ -99,9 +100,15 @@ static void setup(void)
nthreads = tst_ncpus_conf() + 2;
workers = SAFE_MALLOC(sizeof(struct worker) * nthreads);
+ /*
+ * Avoid creating the thread directories in the root of the filesystem
+ * to not hit the root entries limit on a FAT16 filesystem.
+ */
+ SAFE_MKDIR(THREADS_DIR, 0700);
+
for (i = 0; i < nthreads; i++) {
snprintf(workers[i].dir, sizeof(workers[i].dir),
- MNTPOINT "/thread%i", i + 1);
+ THREADS_DIR "/thread%i", i + 1);
SAFE_MKDIR(workers[i].dir, 0700);
}
diff --git a/testcases/kernel/fs/fsstress/fsstress.c b/testcases/kernel/fs/fsstress/fsstress.c
index 42ee696a5..272d87a1f 100644
--- a/testcases/kernel/fs/fsstress/fsstress.c
+++ b/testcases/kernel/fs/fsstress/fsstress.c
@@ -32,7 +32,8 @@
#include "config.h"
#include "global.h"
-#include <tst_common.h>
+#include "tst_common.h"
+
#ifdef HAVE_SYS_PRCTL_H
# include <sys/prctl.h>
#endif
diff --git a/testcases/kernel/fs/fsstress/global.h b/testcases/kernel/fs/fsstress/global.h
index 4ec382426..e7d0cde47 100644
--- a/testcases/kernel/fs/fsstress/global.h
+++ b/testcases/kernel/fs/fsstress/global.h
@@ -33,7 +33,7 @@
#ifndef GLOBAL_H
#define GLOBAL_H
-/* xfs-specific includes */
+#define _GNU_SOURCE
#if defined(NO_XFS)
# include "xfscompat.h"
@@ -42,8 +42,6 @@
# include <attr/attributes.h>
#endif
-/* libc includes */
-
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/time.h>
@@ -58,9 +56,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
-
-#ifndef O_DIRECT
-#define O_DIRECT 040000
-#endif
+#include "lapi/fcntl.h"
#endif
diff --git a/testcases/kernel/fs/lftest/lftest.c b/testcases/kernel/fs/lftest/lftest.c
index 7290fb0df..9e293d9e3 100644
--- a/testcases/kernel/fs/lftest/lftest.c
+++ b/testcases/kernel/fs/lftest/lftest.c
@@ -65,7 +65,7 @@ static void run(void)
tst_res(TINFO, "total time for test to run: %d minute(s) and %d seconds",
diff / 60, diff % 60);
- tst_res(TPASS, "test successfull");
+ tst_res(TPASS, "test successful");
}
static struct tst_test test = {
diff --git a/testcases/kernel/fs/read_all/Makefile b/testcases/kernel/fs/read_all/Makefile
index 0e6dec2d3..fb73e8fbc 100644
--- a/testcases/kernel/fs/read_all/Makefile
+++ b/testcases/kernel/fs/read_all/Makefile
@@ -6,5 +6,6 @@ top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
CFLAGS += -D_GNU_SOURCE -pthread
+read_all: LDLIBS+=-lrt
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/scsi/ltpscsi/scsimain.c b/testcases/kernel/fs/scsi/ltpscsi/scsimain.c
index ae484e0f1..ce23ae1e7 100644
--- a/testcases/kernel/fs/scsi/ltpscsi/scsimain.c
+++ b/testcases/kernel/fs/scsi/ltpscsi/scsimain.c
@@ -28,6 +28,7 @@
[0x12][ |lu][pg cde][res ][al len][cntrl ]
*/
+#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
@@ -53,10 +54,6 @@
#define ME "scsimain: "
-#ifndef O_DIRECT
-#define O_DIRECT 040000
-#endif
-
#define NUMERIC_SCAN_DEF 1 /* change to 0 to make alpha scan default */
//static char * version_str = "0.21 20030513";
diff --git a/testcases/kernel/io/direct_io/diotest3.c b/testcases/kernel/io/direct_io/diotest3.c
index 92f7afaad..ba2fd0473 100644
--- a/testcases/kernel/io/direct_io/diotest3.c
+++ b/testcases/kernel/io/direct_io/diotest3.c
@@ -292,6 +292,7 @@ int main(int argc, char *argv[])
}
unlink(filename);
free(pidlst);
+ fflush(stdout);
total++;
/* Testblock-2: Write with Direct IO, Read without */
@@ -309,6 +310,7 @@ int main(int argc, char *argv[])
}
unlink(filename);
free(pidlst);
+ fflush(stdout);
total++;
/* Testblock-3: Read, Write with Direct IO. */
diff --git a/testcases/kernel/io/direct_io/diotest4.c b/testcases/kernel/io/direct_io/diotest4.c
index f3c9c19d7..45c677b5b 100644
--- a/testcases/kernel/io/direct_io/diotest4.c
+++ b/testcases/kernel/io/direct_io/diotest4.c
@@ -62,7 +62,6 @@
#include <sys/file.h>
#include <fcntl.h>
#include <sys/types.h>
-#include <sys/mman.h>
#include <sys/syscall.h>
#include <errno.h>
diff --git a/testcases/kernel/io/direct_io/diotest6.c b/testcases/kernel/io/direct_io/diotest6.c
index 1905380f0..fb925ff0a 100644
--- a/testcases/kernel/io/direct_io/diotest6.c
+++ b/testcases/kernel/io/direct_io/diotest6.c
@@ -320,6 +320,7 @@ int main(int argc, char *argv[])
}
unlink(filename);
free(pidlst);
+ fflush(stdout);
total++;
/* Testblock-2: Write with Direct IO, Read without */
@@ -337,6 +338,7 @@ int main(int argc, char *argv[])
}
unlink(filename);
free(pidlst);
+ fflush(stdout);
total++;
/* Testblock-3: Read, Write with Direct IO. */
diff --git a/testcases/kernel/io/ltp-aiodio/aiocp.c b/testcases/kernel/io/ltp-aiodio/aiocp.c
index bc0e209b2..6212d8ee8 100644
--- a/testcases/kernel/io/ltp-aiodio/aiocp.c
+++ b/testcases/kernel/io/ltp-aiodio/aiocp.c
@@ -297,8 +297,8 @@ static void run(void)
return;
}
- srcfd = SAFE_OPEN(srcname, srcflags | O_RDONLY, 0666);
- dstfd = SAFE_OPEN(dstname, srcflags | O_RDONLY, 0666);
+ srcfd = SAFE_OPEN(srcname, O_RDONLY, 0666);
+ dstfd = SAFE_OPEN(dstname, O_RDONLY, 0666);
reads = howmany(filesize, buffsize);
diff --git a/testcases/kernel/ipc/semaphore/.gitignore b/testcases/kernel/ipc/semaphore/.gitignore
deleted file mode 100644
index 944e5ca1e..000000000
--- a/testcases/kernel/ipc/semaphore/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/sem01
-/sem02
diff --git a/testcases/kernel/ipc/semaphore/Makefile b/testcases/kernel/ipc/semaphore/Makefile
deleted file mode 100644
index 9ab85745d..000000000
--- a/testcases/kernel/ipc/semaphore/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# testcases/kernel/ipc/semaphore Makefile.
-#
-# Copyright (C) 2009, Cisco Systems 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Ngie Cooper, July 2009
-#
-
-top_srcdir ?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-CPPFLAGS += -I../include
-LDLIBS += -lpthread
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/ipc/semaphore/sem01.c b/testcases/kernel/ipc/semaphore/sem01.c
deleted file mode 100644
index 582624d60..000000000
--- a/testcases/kernel/ipc/semaphore/sem01.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * FILE : sem01.c
- * DESCRIPTION : Creates a semaphore and two processes. The processes
- * each go through a loop where they semdown, delay for a
- * random amount of time, and semup, so they will almost
- * always be fighting for control of the semaphore.
- * HISTORY:
- * 01/15/2001 Paul Larson (plars@us.ibm.com)
- * -written
- * 11/09/2001 Manoj Iyer (manjo@ausin.ibm.com)
- * Modified.
- * - Removed compiler warnings.
- * added exit to the end of function main()
- *
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/ipc.h>
-#include "lapi/sem.h"
-
-int verbose = 0;
-int loops = 100;
-int errors = 0;
-
-int semup(int semid)
-{
- struct sembuf semops;
- semops.sem_num = 0;
- semops.sem_op = 1;
- semops.sem_flg = SEM_UNDO;
- if (semop(semid, &semops, 1) == -1) {
- perror("semup");
- errors++;
- return 1;
- }
- return 0;
-}
-
-int semdown(int semid)
-{
- struct sembuf semops;
- semops.sem_num = 0;
- semops.sem_op = -1;
- semops.sem_flg = SEM_UNDO;
- if (semop(semid, &semops, 1) == -1) {
- perror("semdown");
- errors++;
- return 1;
- }
- return 0;
-}
-
-void delayloop()
-{
- int delay;
- delay = 1 + ((100.0 * rand()) / RAND_MAX);
- if (verbose)
- printf("in delay function for %d microseconds\n", delay);
- usleep(delay);
-}
-
-void mainloop(int semid)
-{
- int i;
- for (i = 0; i < loops; i++) {
- if (semdown(semid)) {
- printf("semdown failed\n");
- }
- if (verbose)
- printf("sem is down\n");
- delayloop();
- if (semup(semid)) {
- printf("semup failed\n");
- }
- if (verbose)
- printf("sem is up\n");
- }
-}
-
-int main(int argc, char *argv[])
-{
- int semid, opt;
- union semun semunion;
- extern char *optarg;
- pid_t pid;
- int chstat;
-
- while ((opt = getopt(argc, argv, "l:vh")) != EOF) {
- switch ((char)opt) {
- case 'l':
- loops = atoi(optarg);
- break;
- case 'v':
- verbose = 1;
- break;
- case 'h':
- default:
- printf("Usage: -l loops [-v]\n");
- exit(1);
- }
- }
-
- /* set up the semaphore */
- if ((semid = semget((key_t) 9142, 1, 0666 | IPC_CREAT)) < 0) {
- printf("error in semget()\n");
- exit(-1);
- }
- semunion.val = 1;
- if (semctl(semid, 0, SETVAL, semunion) == -1) {
- printf("error in semctl\n");
- }
-
- if ((pid = fork()) < 0) {
- printf("fork error\n");
- exit(-1);
- }
- if (pid) {
- /* parent */
- srand(pid);
- mainloop(semid);
- waitpid(pid, &chstat, 0);
- if (!WIFEXITED(chstat)) {
- printf("child exited with status\n");
- exit(-1);
- }
- if (semctl(semid, 0, IPC_RMID, semunion) == -1) {
- printf("error in semctl\n");
- }
- if (errors) {
- printf("FAIL: there were %d errors\n", errors);
- } else {
- printf("PASS: error count is 0\n");
- }
- exit(errors);
- } else {
- /* child */
- mainloop(semid);
- }
- exit(0);
-}
diff --git a/testcases/kernel/kvm/.gitignore b/testcases/kernel/kvm/.gitignore
index 349260359..9638a6fc7 100644
--- a/testcases/kernel/kvm/.gitignore
+++ b/testcases/kernel/kvm/.gitignore
@@ -1 +1,4 @@
/kvm_pagefault01
+/kvm_svm01
+/kvm_svm02
+/kvm_svm03
diff --git a/testcases/kernel/kvm/Makefile b/testcases/kernel/kvm/Makefile
index 6986844be..ce4a5ede2 100644
--- a/testcases/kernel/kvm/Makefile
+++ b/testcases/kernel/kvm/Makefile
@@ -8,8 +8,8 @@ include $(top_srcdir)/include/mk/testcases.mk
ASFLAGS =
CPPFLAGS += -I$(abs_srcdir)/include
GUEST_CPPFLAGS = $(CPPFLAGS) -DCOMPILE_PAYLOAD
-GUEST_CFLAGS = -ffreestanding -O2 -Wall -fno-asynchronous-unwind-tables -mno-mmx -mno-sse
-GUEST_LDFLAGS = -nostdlib -Wl,--build-id=none -fno-stack-protector
+GUEST_CFLAGS = -ffreestanding -O2 -Wall -fno-asynchronous-unwind-tables -fno-stack-protector -mno-mmx -mno-sse
+GUEST_LDFLAGS = -nostdlib -Wl,--build-id=none -z noexecstack
GUEST_LDLIBS =
KVM_LD ?= $(LD)
@@ -48,6 +48,9 @@ endif
lib_guest.o $(ARCH_OBJ): CPPFLAGS := $(GUEST_CPPFLAGS)
lib_guest.o $(ARCH_OBJ): CFLAGS := $(GUEST_CFLAGS)
+kvm_svm03: CFLAGS += -pthread
+kvm_svm03: LDLIBS += -pthread
+
include $(top_srcdir)/include/mk/generic_leaf_target.mk
%-payload.o: %.c lib_guest.o $(ARCH_OBJ)
diff --git a/testcases/kernel/kvm/bootstrap_x86.S b/testcases/kernel/kvm/bootstrap_x86.S
index 5ec4c0b7e..a39c6bea7 100644
--- a/testcases/kernel/kvm/bootstrap_x86.S
+++ b/testcases/kernel/kvm/bootstrap_x86.S
@@ -7,6 +7,9 @@
.set KVM_TEXIT, 0xff
.set RESULT_ADDRESS, 0xfffff000
+.set KVM_GDT_SIZE, 32
+
+.set MSR_VM_HSAVE_PA, 0xc0010117
/*
* This section will be allocated at address 0x1000 and
@@ -31,7 +34,7 @@ protected_mode_entry:
mov %eax, %es
jmp init_memlayout
-.section .data.gdt32, "a", @progbits
+.section .init.gdt32, "a", @progbits
.macro gdt32_entry type:req l=0 d=0 dpl=0 limit=0xfffff g=1 p=1
.4byte \limit & 0xffff
@@ -44,7 +47,7 @@ kvm_gdt:
.8byte 0
gdt32_entry type=0x1a l=0 d=1 /* Code segment protected_mode, 32bits */
gdt32_entry type=0x12 /* Data segment, writable */
- .skip 16 /* Stack and TSS segment descriptors */
+ .skip (KVM_GDT_SIZE-3)*8 /* Stack, TSS and other segment descriptors */
.Lgdt_end:
.global kvm_gdt_desc
@@ -196,6 +199,25 @@ kvm_read_cregs:
pop %edi
ret
+.global kvm_read_sregs
+kvm_read_sregs:
+ push %edi
+ mov 8(%esp), %edi
+ mov %cs, %ax
+ movw %ax, (%edi)
+ mov %ds, %ax
+ movw %ax, 2(%edi)
+ mov %es, %ax
+ movw %ax, 4(%edi)
+ mov %fs, %ax
+ movw %ax, 6(%edi)
+ mov %gs, %ax
+ movw %ax, 8(%edi)
+ mov %ss, %ax
+ movw %ax, 10(%edi)
+ pop %edi
+ ret
+
handle_interrupt:
/* save CPU state */
push %ebp
@@ -331,6 +353,83 @@ kvm_yield:
hlt
ret
+.global kvm_svm_guest_entry
+kvm_svm_guest_entry:
+ call *%eax
+1: hlt
+ jmp 1b
+
+.global kvm_svm_vmrun
+kvm_svm_vmrun:
+ push %edi
+ mov 8(%esp), %edi
+ push %ebx
+ push %esi
+ push %ebp
+
+ clgi
+
+ /* Save full host state */
+ movl $MSR_VM_HSAVE_PA, %ecx
+ rdmsr
+ vmsave
+ push %eax
+
+ /* Load guest registers */
+ push %edi
+ movl (%edi), %eax
+ /* %eax is loaded by vmrun from VMCB */
+ movl 0x0c(%edi), %ebx
+ movl 0x14(%edi), %ecx
+ movl 0x1c(%edi), %edx
+ movl 0x2c(%edi), %esi
+ movl 0x34(%edi), %ebp
+ /* %esp is loaded by vmrun from VMCB */
+ movl 0x24(%edi), %edi
+
+ vmload
+ vmrun
+ vmsave
+
+ /* Clear guest register buffer */
+ push %edi
+ push %ecx
+ movl 8(%esp), %edi
+ addl $4, %edi
+ xorl %eax, %eax
+ mov $32, %ecx
+ pushfl
+ cld
+ rep stosl
+ popfl
+
+ /* Save guest registers */
+ pop %ecx
+ pop %eax
+ pop %edi
+ movl %ebx, 0x0c(%edi)
+ movl %ecx, 0x14(%edi)
+ movl %edx, 0x1c(%edi)
+ movl %eax, 0x24(%edi)
+ movl %esi, 0x2c(%edi)
+ movl %ebp, 0x34(%edi)
+ /* Copy %eax and %esp from VMCB */
+ movl (%edi), %esi
+ movl 0x5f8(%esi), %eax
+ movl %eax, 0x04(%edi)
+ movl 0x5d8(%esi), %eax
+ movl %eax, 0x3c(%edi)
+
+ pop %eax
+ vmload
+ stgi
+
+ pop %ebp
+ pop %esi
+ pop %ebx
+ pop %edi
+ ret
+
.section .bss.pgtables, "aw", @nobits
.global kvm_pagetable
diff --git a/testcases/kernel/kvm/bootstrap_x86_64.S b/testcases/kernel/kvm/bootstrap_x86_64.S
index 9ddbd17ed..b02dd4d92 100644
--- a/testcases/kernel/kvm/bootstrap_x86_64.S
+++ b/testcases/kernel/kvm/bootstrap_x86_64.S
@@ -8,6 +8,9 @@
.set KVM_TCONF, 32
.set KVM_TEXIT, 0xff
.set RESULT_ADDRESS, 0xfffff000
+.set KVM_GDT_SIZE, 32
+
+.set MSR_VM_HSAVE_PA, 0xc0010117
/*
* This section will be allocated at address 0x1000 and
@@ -32,7 +35,7 @@ protected_mode_entry:
mov %eax, %es
jmp init_memlayout
-.section .data.gdt32, "a", @progbits
+.section .init.gdt32, "a", @progbits
.macro gdt32_entry type:req l=0 d=0 dpl=0 limit=0xfffff g=1 p=1
.4byte \limit & 0xffff
@@ -302,6 +305,22 @@ kvm_read_cregs:
mov %rax, 24(%rdi)
retq
+.global kvm_read_sregs
+kvm_read_sregs:
+ mov %cs, %ax
+ movw %ax, (%rdi)
+ mov %ds, %ax
+ movw %ax, 2(%rdi)
+ mov %es, %ax
+ movw %ax, 4(%rdi)
+ mov %fs, %ax
+ movw %ax, 6(%rdi)
+ mov %gs, %ax
+ movw %ax, 8(%rdi)
+ mov %ss, %ax
+ movw %ax, 10(%rdi)
+ retq
+
handle_interrupt:
/* push CPU state */
push %rbp
@@ -457,6 +476,93 @@ kvm_yield:
hlt
ret
+.global kvm_svm_guest_entry
+kvm_svm_guest_entry:
+ call *%rax
+1: hlt
+ jmp 1b
+
+.global kvm_svm_vmrun
+kvm_svm_vmrun:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ clgi
+
+ /* Save full host state */
+ movq $MSR_VM_HSAVE_PA, %rcx
+ rdmsr
+ shlq $32, %rdx
+ orq %rdx, %rax
+ vmsave
+ pushq %rax
+
+ /* Load guest registers */
+ pushq %rdi
+ movq (%rdi), %rax
+ /* %rax is loaded by vmrun from VMCB */
+ movq 0x10(%rdi), %rbx
+ movq 0x18(%rdi), %rcx
+ movq 0x20(%rdi), %rdx
+ movq 0x30(%rdi), %rsi
+ movq 0x38(%rdi), %rbp
+ /* %rsp is loaded by vmrun from VMCB */
+ movq 0x48(%rdi), %r8
+ movq 0x50(%rdi), %r9
+ movq 0x58(%rdi), %r10
+ movq 0x60(%rdi), %r11
+ movq 0x68(%rdi), %r12
+ movq 0x70(%rdi), %r13
+ movq 0x78(%rdi), %r14
+ movq 0x80(%rdi), %r15
+ movq 0x28(%rdi), %rdi
+
+ vmload
+ vmrun
+ vmsave
+
+ /* Save guest registers */
+ movq %rdi, %rax
+ popq %rdi
+ movq %rbx, 0x10(%rdi)
+ movq %rcx, 0x18(%rdi)
+ movq %rdx, 0x20(%rdi)
+ /* %rax contains guest %rdi */
+ movq %rax, 0x28(%rdi)
+ movq %rsi, 0x30(%rdi)
+ movq %rbp, 0x38(%rdi)
+ movq %r8, 0x48(%rdi)
+ movq %r9, 0x50(%rdi)
+ movq %r10, 0x58(%rdi)
+ movq %r11, 0x60(%rdi)
+ movq %r12, 0x68(%rdi)
+ movq %r13, 0x70(%rdi)
+ movq %r14, 0x78(%rdi)
+ movq %r15, 0x80(%rdi)
+ /* copy guest %rax and %rsp from VMCB*/
+ movq (%rdi), %rsi
+ movq 0x5f8(%rsi), %rax
+ movq %rax, 0x08(%rdi)
+ movq 0x5d8(%rsi), %rax
+ movq %rax, 0x40(%rdi)
+
+ /* Reload host state */
+ popq %rax
+ vmload
+
+ stgi
+
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbp
+ popq %rbx
+ retq
.section .bss.pgtables, "aw", @nobits
.global kvm_pagetable
@@ -478,7 +584,7 @@ kvm_pgtable_l4:
kvm_gdt:
.8byte 0
gdt32_entry type=0x1a l=1 limit=0 g=0 /* Code segment long mode */
- .skip 16 /* TSS segment descriptor */
+ .skip (KVM_GDT_SIZE-2)*8 /* TSS and other segment descriptors */
.Lgdt_end:
.global kvm_gdt_desc
diff --git a/testcases/kernel/kvm/include/kvm_common.h b/testcases/kernel/kvm/include/kvm_common.h
index 4e81d8302..377e3f6aa 100644
--- a/testcases/kernel/kvm/include/kvm_common.h
+++ b/testcases/kernel/kvm/include/kvm_common.h
@@ -11,6 +11,14 @@
#define KVM_TNONE -1 /* "No result" status value */
/*
+ * Result value for asynchronous notifications between guest and host.
+ * Do not use this value directly. Call tst_signal_host() or tst_wait_host()
+ * in guest code. The notification must be handled by another host thread
+ * and then the result value must be reset to KVM_TNONE.
+ */
+#define KVM_TSYNC 0xfe
+
+/*
* Result value indicating end of test. If the test program exits using
* the HLT instruction with any valid result value other than KVM_TEXIT or
* TBROK, KVM runner will automatically resume VM execution after printing
diff --git a/testcases/kernel/kvm/include/kvm_guest.h b/testcases/kernel/kvm/include/kvm_guest.h
index ec13c5845..96f246155 100644
--- a/testcases/kernel/kvm/include/kvm_guest.h
+++ b/testcases/kernel/kvm/include/kvm_guest.h
@@ -64,6 +64,20 @@ void tst_brk_(const char *file, const int lineno, int result,
const char *message) __attribute__((noreturn));
#define tst_brk(result, msg) tst_brk_(__FILE__, __LINE__, (result), (msg))
+/*
+ * Send asynchronous notification to host without stopping VM execution and
+ * return immediately. The notification must be handled by another host thread.
+ * The data argument will be passed to host in test_result->file_addr and
+ * can be used to send additional data both ways.
+ */
+void tst_signal_host(void *data);
+
+/*
+ * Call tst_signal_host(data) and wait for host to call
+ * tst_kvm_clear_guest_signal().
+ */
+void tst_wait_host(void *data);
+
void *tst_heap_alloc_aligned(size_t size, size_t align);
void *tst_heap_alloc(size_t size);
diff --git a/testcases/kernel/kvm/include/kvm_host.h b/testcases/kernel/kvm/include/kvm_host.h
index 2359944fd..06bcb5d45 100644
--- a/testcases/kernel/kvm/include/kvm_host.h
+++ b/testcases/kernel/kvm/include/kvm_host.h
@@ -125,13 +125,29 @@ struct kvm_cpuid2 *tst_kvm_get_cpuid(int sysfd);
void tst_kvm_create_instance(struct tst_kvm_instance *inst, size_t ram_size);
/*
- * Execute the given KVM instance and print results.
+ * Execute the given KVM instance and print results. If ioctl(KVM_RUN) is
+ * expected to fail, pass the expected error code in exp_errno, otherwise
+ * set it to zero. Returns last value returned by ioctl(KVM_RUN).
*/
-void tst_kvm_run_instance(struct tst_kvm_instance *inst);
+int tst_kvm_run_instance(struct tst_kvm_instance *inst, int exp_errno);
/*
* Close the given KVM instance.
*/
void tst_kvm_destroy_instance(struct tst_kvm_instance *inst);
+/*
+ * Wait for given VM to call tst_signal_host() or tst_wait_host(). Timeout
+ * value is in milliseconds. Zero means no wait, negative value means wait
+ * forever. Returns 0 if signal was received, KVM_TEXIT if the VM exited
+ * without sending a signal, or -1 if timeout was reached.
+ */
+int tst_kvm_wait_guest(struct tst_kvm_instance *inst, int timeout_ms);
+
+/*
+ * Clear VM signal sent by tst_signal_host(). If the VM is waiting
+ * in tst_wait_host(), this function will signal the VM to resume execution.
+ */
+void tst_kvm_clear_guest_signal(struct tst_kvm_instance *inst);
+
#endif /* KVM_HOST_H_ */
diff --git a/testcases/kernel/kvm/include/kvm_x86.h b/testcases/kernel/kvm/include/kvm_x86.h
index 4f3671135..bc36c0e0f 100644
--- a/testcases/kernel/kvm/include/kvm_x86.h
+++ b/testcases/kernel/kvm/include/kvm_x86.h
@@ -10,6 +10,9 @@
#include "kvm_test.h"
+#define PAGESIZE 0x1000
+#define KVM_GDT_SIZE 32
+
/* Interrupts */
#define X86_INTR_COUNT 256
@@ -38,19 +41,48 @@
#define INTR_SECURITY_ERROR 30
+/* Segment descriptor flags */
+#define SEGTYPE_LDT 0x02
+#define SEGTYPE_TSS 0x09
+#define SEGTYPE_TSS_BUSY 0x0b
+#define SEGTYPE_CALL_GATE 0x0c
+#define SEGTYPE_INTR_GATE 0x0e
+#define SEGTYPE_TRAP_GATE 0x0f
+#define SEGTYPE_RODATA 0x10
+#define SEGTYPE_RWDATA 0x12
+#define SEGTYPE_STACK 0x16
+#define SEGTYPE_CODE 0x1a
+#define SEGTYPE_MASK 0x1f
+
+#define SEGFLAG_NSYSTEM 0x10
+#define SEGFLAG_PRESENT 0x80
+#define SEGFLAG_CODE64 0x200
+#define SEGFLAG_32BIT 0x400
+#define SEGFLAG_PAGE_LIMIT 0x800
+
+
/* CPUID constants */
#define CPUID_GET_INPUT_RANGE 0x80000000
#define CPUID_GET_EXT_FEATURES 0x80000001
+#define CPUID_GET_SVM_FEATURES 0x8000000a
/* Model-specific CPU register constants */
#define MSR_EFER 0xc0000080
+#define MSR_VM_CR 0xc0010114
+#define MSR_VM_HSAVE_PA 0xc0010117
#define EFER_SCE (1 << 0) /* SYSCALL/SYSRET instructions enabled */
#define EFER_LME (1 << 8) /* CPU is running in 64bit mode */
#define EFER_LMA (1 << 10) /* CPU uses 64bit memory paging (read-only) */
#define EFER_NXE (1 << 11) /* Execute disable bit active */
+#define EFER_SVME (1 << 12) /* AMD SVM instructions enabled */
+#define VM_CR_DPD (1 << 0)
+#define VM_CR_R_INIT (1 << 1)
+#define VM_CR_DIS_A20M (1 << 2)
+#define VM_CR_LOCK (1 << 3)
+#define VM_CR_SVMDIS (1 << 4)
/* Control register constants */
#define CR4_VME (1 << 0)
@@ -91,6 +123,25 @@ struct intr_descriptor {
#endif /* defined(__x86_64__) */
} __attribute__((__packed__));
+struct segment_descriptor {
+ unsigned int limit_lo : 16;
+ unsigned int baseaddr_lo : 24;
+ unsigned int flags_lo : 8;
+ unsigned int limit_hi : 4;
+ unsigned int flags_hi : 4;
+ unsigned int baseaddr_hi : 8;
+} __attribute__((__packed__));
+
+struct segment_descriptor64 {
+ unsigned int limit_lo : 16;
+ unsigned int baseaddr_lo : 24;
+ unsigned int flags_lo : 8;
+ unsigned int limit_hi : 4;
+ unsigned int flags_hi : 4;
+ uint64_t baseaddr_hi : 40;
+ uint32_t reserved;
+} __attribute__((__packed__));
+
struct page_table_entry_pae {
unsigned int present: 1;
unsigned int writable: 1;
@@ -116,15 +167,36 @@ struct kvm_cregs {
unsigned long cr0, cr2, cr3, cr4;
};
+struct kvm_sregs {
+ uint16_t cs, ds, es, fs, gs, ss;
+};
+
+struct kvm_regs64 {
+ uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp;
+ uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
+};
+
extern struct page_table_entry_pae kvm_pagetable[];
extern struct intr_descriptor kvm_idt[X86_INTR_COUNT];
+extern struct segment_descriptor kvm_gdt[KVM_GDT_SIZE];
/* Page table helper functions */
uintptr_t kvm_get_page_address_pae(const struct page_table_entry_pae *entry);
+/* Segment descriptor table functions */
+void kvm_set_segment_descriptor(struct segment_descriptor *dst,
+ uint64_t baseaddr, uint32_t limit, unsigned int flags);
+void kvm_parse_segment_descriptor(struct segment_descriptor *src,
+ uint64_t *baseaddr, uint32_t *limit, unsigned int *flags);
+int kvm_find_free_descriptor(const struct segment_descriptor *table,
+ size_t size);
+unsigned int kvm_create_stack_descriptor(struct segment_descriptor *table,
+ size_t tabsize, void *stack_base);
+
/* Functions for querying CPU info and status */
void kvm_get_cpuid(unsigned int eax, unsigned int ecx, struct kvm_cpuid *buf);
void kvm_read_cregs(struct kvm_cregs *buf);
+void kvm_read_sregs(struct kvm_sregs *buf);
uint64_t kvm_rdmsr(unsigned int msr);
void kvm_wrmsr(unsigned int msr, uint64_t value);
diff --git a/testcases/kernel/kvm/include/kvm_x86_svm.h b/testcases/kernel/kvm/include/kvm_x86_svm.h
new file mode 100644
index 000000000..b4b1b80e2
--- /dev/null
+++ b/testcases/kernel/kvm/include/kvm_x86_svm.h
@@ -0,0 +1,166 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 SUSE LLC <mdoucha@suse.cz>
+ *
+ * x86-specific KVM helper functions and structures for AMD SVM
+ */
+
+#ifndef KVM_X86_SVM_H_
+#define KVM_X86_SVM_H_
+
+#include "kvm_x86.h"
+
+/* CPUID_GET_SVM_FEATURES flags returned in EDX */
+#define SVM_CPUID_NESTED_PAGING (1 << 0)
+#define SVM_CPUID_LBR_VIRT (1 << 1)
+#define SVM_CPUID_LOCK (1 << 2)
+#define SVM_CPUID_NRIP_SAVE (1 << 3)
+#define SVM_CPUID_TSC_RATE_MSR (1 << 4)
+#define SVM_CPUID_VMCB_CLEAN (1 << 5)
+#define SVM_CPUID_FLUSH_ASID (1 << 6)
+#define SVM_CPUID_DECODE_ASSIST (1 << 7)
+#define SVM_CPUID_PAUSE_FILTER (1 << 10)
+#define SVM_CPUID_PAUSE_THRESHOLD (1 << 12)
+#define SVM_CPUID_AVIC (1 << 13)
+#define SVM_CPUID_VMSAVE_VIRT (1 << 15)
+#define SVM_CPUID_VGIF (1 << 16)
+#define SVM_CPUID_GMET (1 << 17)
+#define SVM_CPUID_X2AVIC (1 << 18)
+#define SVM_CPUID_SSSCHECK (1 << 19)
+#define SVM_CPUID_SPEC_CTRL (1 << 20)
+#define SVM_CPUID_ROGPT (1 << 21)
+#define SVM_CPUID_HOST_MCE_OVERRIDE (1 << 23)
+#define SVM_CPUID_TLBI_CTL (1 << 24)
+#define SVM_CPUID_NMI_VIRT (1 << 25)
+#define SVM_CPUID_IBS_VIRT (1 << 26)
+
+/* SVM event intercept IDs */
+#define SVM_INTERCEPT_HLT 0x78
+#define SVM_INTERCEPT_VMRUN 0x80
+#define SVM_INTERCEPT_VMLOAD 0x82
+#define SVM_INTERCEPT_VMSAVE 0x83
+#define SVM_INTERCEPT_STGI 0x84
+#define SVM_INTERCEPT_CLGI 0x85
+#define SVM_INTERCEPT_MAX 0x95
+
+/* SVM vmrun exit codes */
+#define SVM_EXIT_HLT 0x78
+#define SVM_EXIT_VMRUN 0x80
+#define SVM_EXIT_VMLOAD 0x82
+#define SVM_EXIT_VMSAVE 0x83
+#define SVM_EXIT_STGI 0x84
+#define SVM_EXIT_CLGI 0x85
+#define SVM_EXIT_AVIC_NOACCEL 0x402
+#define SVM_EXIT_INVALID ((uint64_t)-1)
+
+/* SVM VMCB flags */
+#define SVM_INTR_AVIC (1 << 7)
+
+struct kvm_vmcb_descriptor {
+ uint16_t selector;
+ uint16_t attrib;
+ uint32_t limit;
+ uint64_t base;
+};
+
+struct kvm_vmcb {
+ /* VMCB control area */
+ uint8_t intercepts[20];
+ uint8_t reserved1[44];
+ uint64_t iopm_base_addr;
+ uint64_t msrpm_base_addr;
+ uint64_t tsc_offset;
+ uint32_t guest_asid;
+ uint32_t tlb_control;
+ uint8_t virtual_tpr;
+ uint8_t virtual_irq;
+ unsigned char virt_intr_prio: 4;
+ unsigned char virt_ignore_tpr: 4;
+ uint8_t virt_intr_ctl;
+ uint8_t virt_intr_vector;
+ uint8_t reserved2[3];
+ uint64_t interrupt_shadow;
+ uint64_t exitcode;
+ uint64_t exitinfo1;
+ uint64_t exitinfo2;
+ uint64_t exit_int_info;
+ uint64_t enable_nested_paging;
+ uint64_t avic_bar;
+ uint64_t ghcb_gpa;
+ uint64_t event_injection;
+ uint64_t nested_cr3;
+ uint64_t virt_ext;
+ uint32_t vmcb_clean;
+ uint8_t reserved3[4];
+ uint64_t next_rip;
+ uint8_t instr_len;
+ uint8_t instr_bytes[15];
+ uint64_t avic_backing_page;
+ uint8_t reserved4[8];
+ uint64_t avic_logical_ptr;
+ uint64_t avic_physical_ptr;
+ uint8_t reserved5[8];
+ uint64_t vmsa_pa;
+ uint64_t vmgexit_rax;
+ uint8_t vmgexit_cpl;
+ uint8_t reserved6[0x2e7];
+
+ /* VMCB state save area */
+ struct kvm_vmcb_descriptor es, cs, ss, ds, fs, gs;
+ struct kvm_vmcb_descriptor gdtr, ldtr, idtr, tr;
+ uint8_t reserved7[43];
+ uint8_t cpl;
+ uint8_t reserved8[4];
+ uint64_t efer;
+ uint8_t reserved9[112];
+ uint64_t cr4;
+ uint64_t cr3;
+ uint64_t cr0;
+ uint64_t dr7;
+ uint64_t dr6;
+ uint64_t rflags;
+ uint64_t rip;
+ uint8_t reserved10[88];
+ uint64_t rsp;
+ uint64_t s_cet;
+ uint64_t ssp;
+ uint64_t isst_addr;
+ uint64_t rax;
+ uint64_t star;
+ uint64_t lstar;
+ uint64_t cstar;
+ uint64_t sfmask;
+ uint64_t kernel_gs_base;
+ uint64_t sysenter_cs;
+ uint64_t sysenter_esp;
+ uint64_t sysenter_eip;
+ uint64_t cr2;
+ uint8_t reserved11[32];
+ uint64_t guest_pat;
+ uint8_t padding[0x990];
+};
+
+struct kvm_svm_vcpu {
+ struct kvm_vmcb *vmcb;
+ struct kvm_regs64 regs;
+};
+
+/* AMD SVM virtualization helper functions */
+int kvm_is_svm_supported(void);
+int kvm_get_svm_state(void);
+void kvm_set_svm_state(int enabled);
+
+void kvm_init_svm(void); /* Fully initialize host SVM environment */
+struct kvm_vmcb *kvm_alloc_vmcb(void);
+void kvm_vmcb_copy_gdt_descriptor(struct kvm_vmcb_descriptor *dst,
+ unsigned int gdt_id);
+void kvm_vmcb_set_intercept(struct kvm_vmcb *vmcb, unsigned int id,
+ unsigned int state);
+void kvm_init_guest_vmcb(struct kvm_vmcb *vmcb, uint32_t asid, uint16_t ss,
+ void *rsp, int (*guest_main)(void));
+struct kvm_svm_vcpu *kvm_create_svm_vcpu(int (*guest_main)(void),
+ int alloc_stack);
+
+void kvm_svm_vmrun(struct kvm_svm_vcpu *cpu);
+
+#endif /* KVM_X86_SVM_H_ */
diff --git a/testcases/kernel/kvm/kvm_svm01.c b/testcases/kernel/kvm/kvm_svm01.c
new file mode 100644
index 000000000..32d15526b
--- /dev/null
+++ b/testcases/kernel/kvm/kvm_svm01.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC
+ * Author: Nicolai Stange <nstange@suse.de>
+ * LTP port: Martin Doucha <mdoucha@suse.cz>
+ */
+
+/*\
+ * CVE 2021-3653
+ *
+ * Check that KVM either blocks enabling virtual interrupt controller (AVIC)
+ * in nested VMs or correctly sets up the required memory address translation.
+ * If AVIC is enabled without address translation in the host kernel,
+ * the nested VM will be able to read and write an arbitraty physical memory
+ * page specified by the parent VM. Unauthorized memory access fixed in:
+ *
+ * commit 0f923e07124df069ba68d8bb12324398f4b6b709
+ * Author: Maxim Levitsky <mlevitsk@redhat.com>
+ * Date: Thu Jul 15 01:56:24 2021 +0300
+ *
+ * KVM: nSVM: avoid picking up unsupported bits from L2 in int_ctl (CVE-2021-3653)
+ */
+
+#include "kvm_test.h"
+
+#ifdef COMPILE_PAYLOAD
+#if defined(__i386__) || defined(__x86_64__)
+
+#include "kvm_x86_svm.h"
+
+#define AVIC_REG_ADDR 0x280
+#define AVIC_TEST_VAL 0xec
+#define AVIC_READ_FAIL 0x12ead
+
+#define AVIC_INFO_MASK ((1ULL << 32) | 0xff0)
+#define AVIC_INFO_EXP ((1ULL << 32) | AVIC_REG_ADDR)
+
+static uint32_t * const avic_ptr = (uint32_t *)AVIC_REG_ADDR;
+
+static int guest_main(void)
+{
+ if (*avic_ptr != 0xaaaaaaaa)
+ return AVIC_READ_FAIL;
+
+ *avic_ptr = AVIC_TEST_VAL;
+ return 0;
+}
+
+void main(void)
+{
+ struct kvm_svm_vcpu *vcpu;
+
+ kvm_init_svm();
+ vcpu = kvm_create_svm_vcpu(guest_main, 1);
+
+ /*
+ * Enable AVIC and set both the AVIC base address (where the nested VM
+ * will write) and backing page address (where the parent VM expects
+ * to see the changes) to 0
+ */
+ vcpu->vmcb->virt_intr_ctl |= SVM_INTR_AVIC;
+ vcpu->vmcb->avic_backing_page = 0;
+ vcpu->vmcb->avic_bar = 0;
+ memset((void *)8, 0xaa, PAGESIZE - 8);
+
+ /* Write into AVIC backing page in the nested VM */
+ kvm_svm_vmrun(vcpu);
+
+ switch (vcpu->vmcb->exitcode) {
+ case SVM_EXIT_HLT:
+ if (vcpu->vmcb->rax == AVIC_READ_FAIL) {
+ tst_res(TFAIL, "Nested VM can read host memory");
+ return;
+ }
+
+ if (vcpu->vmcb->rax)
+ tst_brk(TBROK, "Unexpected guest_main() return value");
+
+ break;
+
+ case SVM_EXIT_AVIC_NOACCEL:
+ if ((vcpu->vmcb->exitinfo1 & AVIC_INFO_MASK) == AVIC_INFO_EXP) {
+ tst_res(TPASS, "AVIC register write caused VMEXIT");
+ break;
+ }
+
+ /* unexpected exit, fall through */
+
+ default:
+ tst_brk(TBROK, "Nested VM exited unexpectedly");
+ }
+
+ if (*avic_ptr != AVIC_TEST_VAL) {
+ tst_res(TFAIL, "Write into AVIC ESR redirected to host memory");
+ return;
+ }
+
+ tst_res(TPASS, "Writes into AVIC backing page were not redirected");
+}
+
+#else /* defined(__i386__) || defined(__x86_64__) */
+TST_TEST_TCONF("Test supported only on x86");
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+#else /* COMPILE_PAYLOAD */
+
+static struct tst_test test = {
+ .test_all = tst_kvm_run,
+ .setup = tst_kvm_setup,
+ .cleanup = tst_kvm_cleanup,
+ .supported_archs = (const char *const []) {
+ "x86_64",
+ "x86",
+ NULL
+ },
+ .tags = (struct tst_tag[]){
+ {"linux-git", "0f923e07124d"},
+ {"CVE", "2021-3653"},
+ {}
+ }
+};
+
+#endif /* COMPILE_PAYLOAD */
diff --git a/testcases/kernel/kvm/kvm_svm02.c b/testcases/kernel/kvm/kvm_svm02.c
new file mode 100644
index 000000000..5d2e2ce37
--- /dev/null
+++ b/testcases/kernel/kvm/kvm_svm02.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC
+ * Author: Nicolai Stange <nstange@suse.de>
+ * LTP port: Martin Doucha <mdoucha@suse.cz>
+ */
+
+/*\
+ * CVE 2021-3656
+ *
+ * Check that KVM correctly intercepts VMSAVE and VMLOAD instructions
+ * in a nested virtual machine even when the parent guest disables
+ * intercepting either instruction. If KVM does not override the disabled
+ * intercepts, it'll give the nested VM read/write access to a few bytes
+ * of an arbitrary physical memory page. Unauthorized memory access fixed in:
+ *
+ * commit c7dfa4009965a9b2d7b329ee970eb8da0d32f0bc
+ * Author: Maxim Levitsky <mlevitsk@redhat.com>
+ * Date: Mon Jul 19 16:05:00 2021 +0300
+ *
+ * KVM: nSVM: always intercept VMLOAD/VMSAVE when nested (CVE-2021-3656)
+ */
+
+#include "kvm_test.h"
+
+#ifdef COMPILE_PAYLOAD
+#if defined(__i386__) || defined(__x86_64__)
+
+#include "kvm_x86_svm.h"
+
+static void *vmsave_buf;
+
+/* Load FS, GS, TR and LDTR state from vmsave_buf */
+static int guest_vmload(void)
+{
+ asm (
+ "vmload %0\n"
+ :
+ : "a" (vmsave_buf)
+ );
+ return 0;
+}
+
+/* Save current FS, GS, TR and LDTR state to vmsave_buf */
+static int guest_vmsave(void)
+{
+ asm (
+ "vmsave %0\n"
+ :
+ : "a" (vmsave_buf)
+ );
+ return 0;
+}
+
+static int cmp_descriptor(const struct kvm_vmcb_descriptor *a,
+ const struct kvm_vmcb_descriptor *b)
+{
+ int ret;
+
+ ret = a->selector != b->selector;
+ ret = ret || a->attrib != b->attrib;
+ ret = ret || a->limit != b->limit;
+ ret = ret || a->base != b->base;
+ return ret;
+}
+
+/* Return non-zero if the VMCB fields touched by vmsave/vmload differ */
+static int cmp_vmcb(const struct kvm_vmcb *a, const struct kvm_vmcb *b)
+{
+ int ret;
+
+ ret = cmp_descriptor(&a->fs, &b->fs);
+ ret = ret || cmp_descriptor(&a->gs, &b->gs);
+ ret = ret || cmp_descriptor(&a->tr, &b->tr);
+ ret = ret || cmp_descriptor(&a->ldtr, &b->ldtr);
+ ret = ret || a->kernel_gs_base != b->kernel_gs_base;
+ ret = ret || a->star != b->star;
+ ret = ret || a->lstar != b->lstar;
+ ret = ret || a->cstar != b->cstar;
+ ret = ret || a->sfmask != b->sfmask;
+ ret = ret || a->sysenter_cs != b->sysenter_cs;
+ ret = ret || a->sysenter_esp != b->sysenter_esp;
+ ret = ret || a->sysenter_eip != b->sysenter_eip;
+ return ret;
+}
+
+void main(void)
+{
+ uint16_t ss;
+ uint64_t rsp;
+ struct kvm_svm_vcpu *vcpu;
+
+ kvm_init_svm();
+ vcpu = kvm_create_svm_vcpu(guest_vmload, 1);
+ kvm_vmcb_set_intercept(vcpu->vmcb, SVM_INTERCEPT_VMLOAD, 0);
+ vmsave_buf = kvm_alloc_vmcb();
+
+ /* Save allocated stack for later VM reinit */
+ ss = vcpu->vmcb->ss.selector;
+ rsp = vcpu->vmcb->rsp;
+
+ /* Load partial state from vmsave_buf and save it to vcpu->vmcb */
+ kvm_svm_vmrun(vcpu);
+
+ if (vcpu->vmcb->exitcode != SVM_EXIT_HLT)
+ tst_brk(TBROK, "Nested VM exited unexpectedly");
+
+ if (cmp_vmcb(vcpu->vmcb, vmsave_buf)) {
+ tst_res(TFAIL, "Nested VM can read host memory");
+ return;
+ }
+
+ /* Load state from vcpu->vmcb and save it to vmsave_buf */
+ memset(vmsave_buf, 0xaa, sizeof(struct kvm_vmcb));
+ kvm_init_guest_vmcb(vcpu->vmcb, 1, ss, (void *)rsp, guest_vmsave);
+ kvm_vmcb_set_intercept(vcpu->vmcb, SVM_INTERCEPT_VMSAVE, 0);
+ kvm_svm_vmrun(vcpu);
+
+ if (vcpu->vmcb->exitcode != SVM_EXIT_HLT)
+ tst_brk(TBROK, "Nested VM exited unexpectedly");
+
+ if (cmp_vmcb(vcpu->vmcb, vmsave_buf)) {
+ tst_res(TFAIL, "Nested VM can overwrite host memory");
+ return;
+ }
+
+ tst_res(TPASS, "VMLOAD and VMSAVE were intercepted by kernel");
+}
+
+#else /* defined(__i386__) || defined(__x86_64__) */
+TST_TEST_TCONF("Test supported only on x86");
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+#else /* COMPILE_PAYLOAD */
+
+static struct tst_test test = {
+ .test_all = tst_kvm_run,
+ .setup = tst_kvm_setup,
+ .cleanup = tst_kvm_cleanup,
+ .supported_archs = (const char *const []) {
+ "x86_64",
+ "x86",
+ NULL
+ },
+ .tags = (struct tst_tag[]){
+ {"linux-git", "c7dfa4009965"},
+ {"CVE", "2021-3656"},
+ {}
+ }
+};
+
+#endif /* COMPILE_PAYLOAD */
diff --git a/testcases/kernel/kvm/kvm_svm03.c b/testcases/kernel/kvm/kvm_svm03.c
new file mode 100644
index 000000000..87164d013
--- /dev/null
+++ b/testcases/kernel/kvm/kvm_svm03.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC
+ * Author: Nicolai Stange <nstange@suse.de>
+ * LTP port: Martin Doucha <mdoucha@suse.cz>
+ */
+
+/*\
+ * Check that KVM correctly intercepts the CLGI instruction in a nested
+ * virtual machine even when the parent guest disables intercept.
+ * If KVM does not override the disabled intercept, it'll allow the nested VM
+ * to hold the physical CPU indefinitely and potentially perform a denial
+ * of service attack against the host kernel. CPU lockup fixed in:
+ *
+ * commit 91b7130cb6606d8c6b3b77e54426b3f3a83f48b1
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ * Date: Fri May 22 12:28:52 2020 -0400
+ *
+ * KVM: SVM: preserve VGIF across VMCB switch
+ */
+
+#include "kvm_test.h"
+
+#ifdef COMPILE_PAYLOAD
+#if defined(__i386__) || defined(__x86_64__)
+
+#include "kvm_x86_svm.h"
+
+/* Disable global interrupts */
+static int guest_clgi(void)
+{
+ int ret, *result = (int *)KVM_RESULT_BASEADDR;
+
+ /*
+ * Make sure that result page is present in memory. CLGI may disable
+ * page fault handling on the current CPU. The actual value
+ * at that address is irrelevant.
+ */
+ ret = *result;
+
+ /* Disable global interrupts */
+ asm ("clgi");
+
+ /* Signal host to kill the VM and wait */
+ tst_wait_host(NULL);
+ return ret;
+}
+
+void main(void)
+{
+ struct kvm_svm_vcpu *vcpu;
+
+ kvm_init_svm();
+ vcpu = kvm_create_svm_vcpu(guest_clgi, 1);
+ kvm_vmcb_set_intercept(vcpu->vmcb, SVM_INTERCEPT_CLGI, 0);
+ kvm_svm_vmrun(vcpu);
+
+ if (vcpu->vmcb->exitcode != SVM_EXIT_HLT)
+ tst_brk(TBROK, "Nested VM exited unexpectedly");
+}
+
+#else /* defined(__i386__) || defined(__x86_64__) */
+TST_TEST_TCONF("Test supported only on x86");
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+#else /* COMPILE_PAYLOAD */
+
+#include <pthread.h>
+#include "tst_safe_pthread.h"
+#include "tst_safe_clocks.h"
+
+static struct tst_kvm_instance test_vm = { .vm_fd = -1 };
+static pthread_mutex_t mutex;
+static int mutex_init;
+
+static void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
+{
+
+}
+
+static void *vm_thread(void *arg)
+{
+ SAFE_PTHREAD_MUTEX_LOCK(&mutex);
+ tst_kvm_run_instance(&test_vm, EINTR);
+ SAFE_PTHREAD_MUTEX_UNLOCK(&mutex);
+ return arg;
+}
+
+static void setup(void)
+{
+ struct sigaction sa = { .sa_handler = sighandler };
+ pthread_mutexattr_t attr;
+
+ SAFE_PTHREAD_MUTEXATTR_INIT(&attr);
+ SAFE_PTHREAD_MUTEXATTR_SETTYPE(&attr, PTHREAD_MUTEX_NORMAL);
+ SAFE_PTHREAD_MUTEX_INIT(&mutex, &attr);
+ mutex_init = 1;
+ SAFE_PTHREAD_MUTEXATTR_DESTROY(&attr);
+ SAFE_SIGACTION(SIGUSR1, &sa, NULL);
+}
+
+static void run(void)
+{
+ struct timespec timeout;
+ pthread_t tid;
+ int ret;
+
+ tst_kvm_create_instance(&test_vm, DEFAULT_RAM_SIZE);
+
+ SAFE_PTHREAD_CREATE(&tid, NULL, vm_thread, NULL);
+ ret = tst_kvm_wait_guest(&test_vm, 2000);
+
+ if (ret == KVM_TEXIT) {
+ SAFE_PTHREAD_JOIN(tid, NULL);
+ tst_brk(TCONF, "Guest exited early");
+ }
+
+ if (ret)
+ tst_brk(TBROK, "Wait for guest initialization timed out");
+
+ SAFE_PTHREAD_KILL(tid, SIGUSR1);
+ SAFE_CLOCK_GETTIME(CLOCK_REALTIME, &timeout);
+ timeout.tv_sec += 2;
+
+ if (SAFE_PTHREAD_MUTEX_TIMEDLOCK(&mutex, &timeout)) {
+ tst_kvm_clear_guest_signal(&test_vm);
+ tst_res(TFAIL, "VM thread does not respond to signals");
+ } else {
+ SAFE_PTHREAD_MUTEX_UNLOCK(&mutex);
+ tst_res(TPASS, "VM thread was interrupted by signal");
+ }
+
+ SAFE_PTHREAD_JOIN(tid, NULL);
+ tst_kvm_destroy_instance(&test_vm);
+ tst_free_all();
+}
+
+static void cleanup(void)
+{
+ /*
+ * If the mutex is locked, the VM is likely still running, cannot
+ * clean up anything
+ */
+ if (!mutex_init || SAFE_PTHREAD_MUTEX_TRYLOCK(&mutex))
+ return;
+
+ if (!SAFE_PTHREAD_MUTEX_UNLOCK(&mutex))
+ SAFE_PTHREAD_MUTEX_DESTROY(&mutex);
+
+ tst_kvm_destroy_instance(&test_vm);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .min_cpus = 2,
+ .supported_archs = (const char *const []) {
+ "x86_64",
+ "x86",
+ NULL
+ },
+ .tags = (struct tst_tag[]){
+ {"linux-git", "91b7130cb660"},
+ {}
+ }
+};
+
+#endif /* COMPILE_PAYLOAD */
diff --git a/testcases/kernel/kvm/lib_guest.c b/testcases/kernel/kvm/lib_guest.c
index d237293fc..f3e21d3d6 100644
--- a/testcases/kernel/kvm/lib_guest.c
+++ b/testcases/kernel/kvm/lib_guest.c
@@ -82,7 +82,7 @@ char *ptr2hex(char *dest, uintptr_t val)
uintptr_t tmp;
char *ret = dest;
- for (i = 4; val >> i; i += 4)
+ for (i = 4, tmp = val >> 4; tmp; i += 4, tmp >>= 4)
;
do {
@@ -155,6 +155,22 @@ void tst_brk_(const char *file, const int lineno, int result,
kvm_exit();
}
+void tst_signal_host(void *data)
+{
+ test_result->file_addr = (uintptr_t)data;
+ test_result->result = KVM_TSYNC;
+}
+
+void tst_wait_host(void *data)
+{
+ volatile int32_t *vres = &test_result->result;
+
+ tst_signal_host(data);
+
+ while (*vres != KVM_TNONE)
+ ;
+}
+
void tst_handle_interrupt(struct kvm_interrupt_frame *ifrm, long vector,
unsigned long errcode)
{
diff --git a/testcases/kernel/kvm/lib_host.c b/testcases/kernel/kvm/lib_host.c
index 2782e68b0..8e3d6094e 100644
--- a/testcases/kernel/kvm/lib_host.c
+++ b/testcases/kernel/kvm/lib_host.c
@@ -10,6 +10,8 @@
#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"
+#include "tst_clocks.h"
+#include "tst_timer.h"
#include "kvm_host.h"
static struct tst_kvm_instance test_vm = { .vm_fd = -1 };
@@ -234,14 +236,28 @@ void tst_kvm_create_instance(struct tst_kvm_instance *inst, size_t ram_size)
inst->result->message[0] = '\0';
}
-void tst_kvm_run_instance(struct tst_kvm_instance *inst)
+int tst_kvm_run_instance(struct tst_kvm_instance *inst, int exp_errno)
{
struct kvm_regs regs;
+ int ret;
while (1) {
inst->result->result = KVM_TNONE;
inst->result->message[0] = '\0';
- SAFE_IOCTL(inst->vcpu_fd, KVM_RUN, 0);
+ errno = 0;
+ ret = ioctl(inst->vcpu_fd, KVM_RUN, 0);
+
+ if (ret == -1) {
+ if (errno == exp_errno)
+ return ret;
+
+ tst_brk(TBROK | TERRNO, "ioctl(KVM_RUN) failed");
+ }
+
+ if (ret < 0) {
+ tst_brk(TBROK | TERRNO,
+ "Invalid ioctl(KVM_RUN) return value %d", ret);
+ }
if (inst->vcpu_info->exit_reason != KVM_EXIT_HLT) {
SAFE_IOCTL(inst->vcpu_fd, KVM_GET_REGS, &regs);
@@ -255,6 +271,8 @@ void tst_kvm_run_instance(struct tst_kvm_instance *inst)
tst_kvm_print_result(inst);
}
+
+ return ret;
}
void tst_kvm_destroy_instance(struct tst_kvm_instance *inst)
@@ -272,6 +290,37 @@ void tst_kvm_destroy_instance(struct tst_kvm_instance *inst)
memset(inst->ram, 0, sizeof(inst->ram));
}
+int tst_kvm_wait_guest(struct tst_kvm_instance *inst, int timeout_ms)
+{
+ volatile struct tst_kvm_result *result = inst->result;
+ int32_t res;
+ struct timespec start, now;
+
+ if (timeout_ms >= 0)
+ tst_clock_gettime(CLOCK_MONOTONIC, &start);
+
+ while ((res = result->result) != KVM_TSYNC) {
+ if (res == KVM_TEXIT)
+ return res;
+
+ if (timeout_ms >= 0) {
+ tst_clock_gettime(CLOCK_MONOTONIC, &now);
+
+ if (tst_timespec_diff_ms(now, start) >= timeout_ms)
+ return -1;
+ }
+
+ usleep(1000);
+ }
+
+ return 0;
+}
+
+void tst_kvm_clear_guest_signal(struct tst_kvm_instance *inst)
+{
+ inst->result->result = KVM_TNONE;
+}
+
void tst_kvm_setup(void)
{
@@ -280,7 +329,7 @@ void tst_kvm_setup(void)
void tst_kvm_run(void)
{
tst_kvm_create_instance(&test_vm, DEFAULT_RAM_SIZE);
- tst_kvm_run_instance(&test_vm);
+ tst_kvm_run_instance(&test_vm, 0);
tst_kvm_destroy_instance(&test_vm);
tst_free_all();
}
diff --git a/testcases/kernel/kvm/lib_x86.c b/testcases/kernel/kvm/lib_x86.c
index dc2354b10..3e6656f11 100644
--- a/testcases/kernel/kvm/lib_x86.c
+++ b/testcases/kernel/kvm/lib_x86.c
@@ -5,7 +5,9 @@
* x86-specific KVM helper functions
*/
-#include "kvm_x86.h"
+#include "kvm_x86_svm.h"
+
+void kvm_svm_guest_entry(void);
struct kvm_interrupt_frame {
uintptr_t eip, cs, eflags, esp, ss;
@@ -110,6 +112,98 @@ uintptr_t kvm_get_page_address_pae(const struct page_table_entry_pae *entry)
return entry->address << 12;
}
+#ifdef __x86_64__
+static void kvm_set_segment_descriptor64(struct segment_descriptor64 *dst,
+ uint64_t baseaddr, uint32_t limit, unsigned int flags)
+{
+
+ dst->baseaddr_lo = baseaddr & 0xffffff;
+ dst->baseaddr_hi = baseaddr >> 24;
+ dst->limit_lo = limit & 0xffff;
+ dst->limit_hi = limit >> 16;
+ dst->flags_lo = flags & 0xff;
+ dst->flags_hi = (flags >> 8) & 0xf;
+ dst->reserved = 0;
+}
+#endif
+
+void kvm_set_segment_descriptor(struct segment_descriptor *dst,
+ uint64_t baseaddr, uint32_t limit, unsigned int flags)
+{
+ if (limit >> 20)
+ tst_brk(TBROK, "Segment limit out of range");
+
+#ifdef __x86_64__
+ /* System descriptors have double size in 64bit mode */
+ if (!(flags & SEGFLAG_NSYSTEM)) {
+ kvm_set_segment_descriptor64((struct segment_descriptor64 *)dst,
+ baseaddr, limit, flags);
+ return;
+ }
+#endif
+
+ if (baseaddr >> 32)
+ tst_brk(TBROK, "Segment base address out of range");
+
+ dst->baseaddr_lo = baseaddr & 0xffffff;
+ dst->baseaddr_hi = baseaddr >> 24;
+ dst->limit_lo = limit & 0xffff;
+ dst->limit_hi = limit >> 16;
+ dst->flags_lo = flags & 0xff;
+ dst->flags_hi = (flags >> 8) & 0xf;
+}
+
+void kvm_parse_segment_descriptor(struct segment_descriptor *src,
+ uint64_t *baseaddr, uint32_t *limit, unsigned int *flags)
+{
+ if (baseaddr) {
+ *baseaddr = (((uint64_t)src->baseaddr_hi) << 24) |
+ src->baseaddr_lo;
+ }
+
+ if (limit)
+ *limit = (((uint32_t)src->limit_hi) << 16) | src->limit_lo;
+
+ if (flags)
+ *flags = (((uint32_t)src->flags_hi) << 8) | src->flags_lo;
+}
+
+int kvm_find_free_descriptor(const struct segment_descriptor *table,
+ size_t size)
+{
+ const struct segment_descriptor *ptr;
+ size_t i;
+
+ for (i = 0, ptr = table; i < size; i++, ptr++) {
+ if (!(ptr->flags_lo & SEGFLAG_PRESENT))
+ return i;
+
+#ifdef __x86_64__
+ /* System descriptors have double size in 64bit mode */
+ if (!(ptr->flags_lo & SEGFLAG_NSYSTEM)) {
+ ptr++;
+ i++;
+ }
+#endif
+ }
+
+ return -1;
+}
+
+unsigned int kvm_create_stack_descriptor(struct segment_descriptor *table,
+ size_t tabsize, void *stack_base)
+{
+ int ret = kvm_find_free_descriptor(table, tabsize);
+
+ if (ret < 0)
+ tst_brk(TBROK, "Descriptor table is full");
+
+ kvm_set_segment_descriptor(table + ret, 0,
+ (((uintptr_t)stack_base) - 1) >> 12, SEGTYPE_STACK |
+ SEGFLAG_PRESENT | SEGFLAG_32BIT | SEGFLAG_PAGE_LIMIT);
+ return ret;
+}
+
void kvm_get_cpuid(unsigned int eax, unsigned int ecx, struct kvm_cpuid *buf)
{
asm (
@@ -148,3 +242,154 @@ uintptr_t kvm_get_interrupt_ip(const struct kvm_interrupt_frame *ifrm)
{
return ifrm->eip;
}
+
+int kvm_is_svm_supported(void)
+{
+ struct kvm_cpuid buf;
+
+ kvm_get_cpuid(CPUID_GET_INPUT_RANGE, 0, &buf);
+
+ if (buf.eax < CPUID_GET_EXT_FEATURES)
+ return 0;
+
+ kvm_get_cpuid(CPUID_GET_EXT_FEATURES, 0, &buf);
+ return buf.ecx & 0x4;
+}
+
+int kvm_get_svm_state(void)
+{
+ return kvm_rdmsr(MSR_EFER) & EFER_SVME;
+}
+
+void kvm_set_svm_state(int enabled)
+{
+ uint64_t value;
+
+ if (!kvm_is_svm_supported())
+ tst_brk(TCONF, "CPU does not support SVM");
+
+ if (kvm_rdmsr(MSR_VM_CR) & VM_CR_SVMDIS)
+ tst_brk(TCONF, "SVM is supported but disabled");
+
+ value = kvm_rdmsr(MSR_EFER);
+
+ if (enabled)
+ value |= EFER_SVME;
+ else
+ value &= ~EFER_SVME;
+
+ kvm_wrmsr(MSR_EFER, value);
+}
+
+struct kvm_vmcb *kvm_alloc_vmcb(void)
+{
+ struct kvm_vmcb *ret;
+
+ ret = tst_heap_alloc_aligned(sizeof(struct kvm_vmcb), PAGESIZE);
+ memset(ret, 0, sizeof(struct kvm_vmcb));
+ return ret;
+}
+
+void kvm_init_svm(void)
+{
+ kvm_set_svm_state(1);
+ kvm_wrmsr(MSR_VM_HSAVE_PA, (uintptr_t)kvm_alloc_vmcb());
+}
+
+void kvm_vmcb_copy_gdt_descriptor(struct kvm_vmcb_descriptor *dst,
+ unsigned int gdt_id)
+{
+ uint64_t baseaddr;
+ uint32_t limit;
+ unsigned int flags;
+
+ if (gdt_id >= KVM_GDT_SIZE)
+ tst_brk(TBROK, "GDT descriptor ID out of range");
+
+ kvm_parse_segment_descriptor(kvm_gdt + gdt_id, &baseaddr, &limit,
+ &flags);
+
+ if (!(flags & SEGFLAG_PRESENT)) {
+ memset(dst, 0, sizeof(struct kvm_vmcb_descriptor));
+ return;
+ }
+
+ if (flags & SEGFLAG_PAGE_LIMIT)
+ limit = (limit << 12) | 0xfff;
+
+ dst->selector = gdt_id << 3;
+ dst->attrib = flags;
+ dst->limit = limit;
+ dst->base = baseaddr;
+}
+
+void kvm_vmcb_set_intercept(struct kvm_vmcb *vmcb, unsigned int id,
+ unsigned int state)
+{
+ unsigned int addr = id / 8, bit = 1 << (id % 8);
+
+ if (id >= SVM_INTERCEPT_MAX)
+ tst_brk(TBROK, "Invalid SVM intercept ID");
+
+ if (state)
+ vmcb->intercepts[addr] |= bit;
+ else
+ vmcb->intercepts[addr] &= ~bit;
+}
+
+void kvm_init_guest_vmcb(struct kvm_vmcb *vmcb, uint32_t asid, uint16_t ss,
+ void *rsp, int (*guest_main)(void))
+{
+ struct kvm_cregs cregs;
+ struct kvm_sregs sregs;
+
+ kvm_read_cregs(&cregs);
+ kvm_read_sregs(&sregs);
+
+ kvm_vmcb_set_intercept(vmcb, SVM_INTERCEPT_VMRUN, 1);
+ kvm_vmcb_set_intercept(vmcb, SVM_INTERCEPT_HLT, 1);
+
+ kvm_vmcb_copy_gdt_descriptor(&vmcb->es, sregs.es >> 3);
+ kvm_vmcb_copy_gdt_descriptor(&vmcb->cs, sregs.cs >> 3);
+ kvm_vmcb_copy_gdt_descriptor(&vmcb->ss, ss);
+ kvm_vmcb_copy_gdt_descriptor(&vmcb->ds, sregs.ds >> 3);
+ kvm_vmcb_copy_gdt_descriptor(&vmcb->fs, sregs.fs >> 3);
+ kvm_vmcb_copy_gdt_descriptor(&vmcb->gs, sregs.gs >> 3);
+ vmcb->gdtr.base = (uintptr_t)kvm_gdt;
+ vmcb->gdtr.limit = (KVM_GDT_SIZE*sizeof(struct segment_descriptor)) - 1;
+ vmcb->idtr.base = (uintptr_t)kvm_idt;
+ vmcb->idtr.limit = (X86_INTR_COUNT*sizeof(struct intr_descriptor)) - 1;
+
+ vmcb->guest_asid = asid;
+ vmcb->efer = kvm_rdmsr(MSR_EFER);
+ vmcb->cr0 = cregs.cr0;
+ vmcb->cr3 = cregs.cr3;
+ vmcb->cr4 = cregs.cr4;
+ vmcb->rip = (uintptr_t)kvm_svm_guest_entry;
+ vmcb->rax = (uintptr_t)guest_main;
+ vmcb->rsp = (uintptr_t)rsp;
+ vmcb->rflags = 0x200; /* Interrupts enabled */
+}
+
+struct kvm_svm_vcpu *kvm_create_svm_vcpu(int (*guest_main)(void),
+ int alloc_stack)
+{
+ uint16_t ss = 0;
+ char *stack = NULL;
+ struct kvm_vmcb *vmcb;
+ struct kvm_svm_vcpu *ret;
+
+ vmcb = kvm_alloc_vmcb();
+
+ if (alloc_stack) {
+ stack = tst_heap_alloc_aligned(2 * PAGESIZE, PAGESIZE);
+ ss = kvm_create_stack_descriptor(kvm_gdt, KVM_GDT_SIZE, stack);
+ stack += 2 * PAGESIZE;
+ }
+
+ kvm_init_guest_vmcb(vmcb, 1, ss, stack, guest_main);
+ ret = tst_heap_alloc(sizeof(struct kvm_svm_vcpu));
+ memset(ret, 0, sizeof(struct kvm_svm_vcpu));
+ ret->vmcb = vmcb;
+ return ret;
+}
diff --git a/testcases/kernel/kvm/linker/x86.lds b/testcases/kernel/kvm/linker/x86.lds
index 95edb0be0..6e69c4d0f 100644
--- a/testcases/kernel/kvm/linker/x86.lds
+++ b/testcases/kernel/kvm/linker/x86.lds
@@ -4,6 +4,7 @@ PHDRS
{
headers PT_PHDR PHDRS ;
text PT_LOAD FILEHDR PHDRS ;
+ data PT_LOAD ;
bss PT_LOAD ;
}
@@ -18,7 +19,7 @@ SECTIONS
.init.boot :
{
*(.init.protected_mode)
- *(.data.gdt32)
+ *(.init.gdt32)
*(.init.memlayout)
} :text
@@ -40,7 +41,7 @@ SECTIONS
{
*(.data.strings)
*(.data)
- }
+ } :data
.preinit_array :
{
diff --git a/testcases/kernel/kvm/linker/x86_64.lds b/testcases/kernel/kvm/linker/x86_64.lds
index ac372f863..9e62aa5ad 100644
--- a/testcases/kernel/kvm/linker/x86_64.lds
+++ b/testcases/kernel/kvm/linker/x86_64.lds
@@ -4,6 +4,7 @@ PHDRS
{
headers PT_PHDR PHDRS ;
text PT_LOAD FILEHDR PHDRS ;
+ data PT_LOAD ;
bss PT_LOAD ;
}
@@ -18,7 +19,7 @@ SECTIONS
.init.boot :
{
*(.init.protected_mode)
- *(.data.gdt32)
+ *(.init.gdt32)
*(.init.memlayout)
} :text
@@ -40,7 +41,7 @@ SECTIONS
{
*(.data.strings)
*(.data)
- }
+ } :data
.preinit_array :
{
diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore
index 06e125d03..7258489ed 100644
--- a/testcases/kernel/mem/.gitignore
+++ b/testcases/kernel/mem/.gitignore
@@ -33,6 +33,7 @@
/hugetlb/hugemmap/hugemmap29
/hugetlb/hugemmap/hugemmap30
/hugetlb/hugemmap/hugemmap31
+/hugetlb/hugemmap/hugemmap32
/hugetlb/hugeshmat/hugeshmat01
/hugetlb/hugeshmat/hugeshmat02
/hugetlb/hugeshmat/hugeshmat03
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/Makefile b/testcases/kernel/mem/hugetlb/hugemmap/Makefile
index 6f10807cd..2d651b4aa 100644
--- a/testcases/kernel/mem/hugetlb/hugemmap/Makefile
+++ b/testcases/kernel/mem/hugetlb/hugemmap/Makefile
@@ -8,5 +8,4 @@ include $(top_srcdir)/include/mk/testcases.mk
include $(abs_srcdir)/../Makefile.inc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
-hugemmap15: CFLAGS+=-O0
hugemmap06: CFLAGS+=-pthread
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap15.c b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap15.c
index 07e65a160..4d1984070 100644
--- a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap15.c
+++ b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap15.c
@@ -19,6 +19,10 @@
* remap, or because the icache happens to get flushed in the interim.
*/
+#if defined(__clang__)
+ #pragma clang optimize off
+#endif
+
#define _GNU_SOURCE
#include "hugetlb.h"
@@ -27,16 +31,7 @@
defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) || \
defined(__i386__) || defined(__x86_64__) || defined(__arm__)
-#include <stdio.h>
-#include <stdlib.h>
#include <setjmp.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/mman.h>
-#include <ucontext.h>
-#include <limits.h>
-#include <sys/param.h>
-#include <sys/types.h>
#define SUCC_JMP 1
#define FAIL_JMP 2
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c
index a465aadec..158a03010 100644
--- a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c
+++ b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c
@@ -23,7 +23,7 @@
static int fd = -1;
static unsigned long slice_boundary;
-static long hpage_size, page_size;
+static unsigned long hpage_size, page_size;
static int init_slice_boundary(int fd)
{
@@ -44,6 +44,13 @@ static int init_slice_boundary(int fd)
heap = malloc(1);
free(heap);
+ /* Avoid underflow on systems with large huge pages.
+ * The additionally plus heap address is to reduce the possibility
+ * of MAP_FIXED stomp over existing mappings.
+ */
+ while (slice_boundary + slice_size < (unsigned long)heap + 2*hpage_size)
+ slice_boundary += slice_size;
+
/* Find 2 neighbour slices with couple huge pages free
* around slice boundary.
* 16 is the maximum number of slices (low/high)
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap32.c b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap32.c
new file mode 100644
index 000000000..d27e5b8b2
--- /dev/null
+++ b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap32.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023, IBM Corporation.
+ * Author: Tarun Sahu
+ */
+
+/*\
+ * [Description]
+ *
+ * Before kernel version 5.10-rc7, there was a bug that resulted in a "Bad Page
+ * State" error when freeing gigantic hugepages. This happened because the
+ * struct page entry compound_nr, which overlapped with page->mapping in the
+ * first tail page, was not cleared, causing the error. To ensure that this
+ * issue does not reoccur as struct page keeps changing and some fields are
+ * managed by folio, this test checks that freeing gigantic hugepages does not
+ * produce the above-mentioned error.
+ */
+
+#define _GNU_SOURCE
+#include <dirent.h>
+
+#include <stdio.h>
+
+#include "hugetlb.h"
+
+#define PATH_HUGEPAGE "/sys/kernel/mm/hugepages"
+#define GIGANTIC_MIN_ORDER 10
+
+static int org_g_hpages;
+static char g_hpage_path[4096];
+
+static void run_test(void)
+{
+ if (FILE_PRINTF(g_hpage_path, "%d", 1))
+ tst_brk(TCONF, "Can't update the gigantic hugepages.");
+ SAFE_FILE_PRINTF(g_hpage_path, "%d", 0);
+
+ if (tst_taint_check())
+ tst_res(TFAIL, "Freeing Gigantic pages resulted in Bad Page State bug.");
+ else
+ tst_res(TPASS, "Successfully freed the gigantic hugepages");
+}
+
+static void setup(void)
+{
+ DIR *dir;
+ struct dirent *ent;
+ unsigned long hpage_size;
+
+ if (access(PATH_HUGEPAGE, F_OK))
+ tst_brk(TCONF, "hugetlbfs is not supported");
+
+ dir = SAFE_OPENDIR(PATH_HUGEPAGE);
+ while ((ent = SAFE_READDIR(dir))) {
+ if ((sscanf(ent->d_name, "hugepages-%lukB", &hpage_size) == 1) &&
+ is_hugetlb_gigantic(hpage_size * 1024)) {
+ sprintf(g_hpage_path, "%s/%s/%s", PATH_HUGEPAGE,
+ ent->d_name, "nr_hugepages");
+ break;
+ }
+ }
+ if (!g_hpage_path[0])
+ tst_brk(TCONF, "Gigantic hugepages not supported");
+
+ SAFE_CLOSEDIR(dir);
+
+ SAFE_FILE_PRINTF("/proc/sys/vm/drop_caches", "3");
+ SAFE_FILE_PRINTF("/proc/sys/vm/compact_memory", "1");
+
+ if (tst_available_mem() < (long long)hpage_size) {
+ g_hpage_path[0] = '\0';
+ tst_brk(TCONF, "No enough memory for gigantic hugepage reservation");
+ }
+
+ SAFE_FILE_LINES_SCANF(g_hpage_path, "%d", &org_g_hpages);
+}
+
+static void cleanup(void)
+{
+ if (g_hpage_path[0])
+ SAFE_FILE_PRINTF(g_hpage_path, "%d", org_g_hpages);
+}
+
+static struct tst_test test = {
+ .tags = (struct tst_tag[]) {
+ {"linux-git", "ba9c1201beaa"},
+ {"linux-git", "a01f43901cfb"},
+ {}
+ },
+ .needs_root = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run_test,
+ .taint_check = TST_TAINT_B,
+};
diff --git a/testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat04.c b/testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat04.c
index 50efa8a52..8ad745d5b 100644
--- a/testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat04.c
+++ b/testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat04.c
@@ -27,7 +27,6 @@
static long huge_free;
static long huge_free2;
-static long orig_shmmax = -1, new_shmmax;
static void shared_hugepage(void);
@@ -81,14 +80,13 @@ static void shared_hugepage(void)
static void setup(void)
{
long hpage_size, orig_hugepages;
+ unsigned long new_shmmax;
orig_hugepages = get_sys_tune("nr_hugepages");
- SAFE_FILE_SCANF(PATH_SHMMAX, "%ld", &orig_shmmax);
- SAFE_FILE_PRINTF(PATH_SHMMAX, "%ld", (long)SIZE);
- SAFE_FILE_SCANF(PATH_SHMMAX, "%ld", &new_shmmax);
+ SAFE_FILE_SCANF(PATH_SHMMAX, "%lu", &new_shmmax);
if (new_shmmax < SIZE)
- tst_brk(TCONF, "shmmax too low, have: %ld", new_shmmax);
+ tst_brk(TCONF, "shmmax too low, have: %lu", new_shmmax);
hpage_size = SAFE_READ_MEMINFO("Hugepagesize:") * 1024;
@@ -96,12 +94,6 @@ static void setup(void)
tst_reserve_hugepages(&hp);
}
-static void cleanup(void)
-{
- if (orig_shmmax != -1)
- SAFE_FILE_PRINTF(PATH_SHMMAX, "%ld", orig_shmmax);
-}
-
static struct tst_test test = {
.tags = (const struct tst_tag[]) {
{"linux-git", "c5c99429fa57"},
@@ -114,6 +106,9 @@ static struct tst_test test = {
.test = test_hugeshmat,
.min_mem_avail = 2048,
.setup = setup,
- .cleanup = cleanup,
.hugepages = {1, TST_NEEDS},
+ .save_restore = (const struct tst_path_val[]) {
+ {PATH_SHMMAX, "1073741824", TST_SR_TCONF_MISSING | TST_SR_TBROK_RO},
+ {}
+ },
};
diff --git a/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl01.c b/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl01.c
index 11cd69050..a68b0da75 100644
--- a/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl01.c
+++ b/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl01.c
@@ -53,10 +53,10 @@ static void func_set(void);
static void func_rmid(void);
static void *set_shmat(void);
-struct tcase {
+static struct tcase {
int cmd;
- void (*func_test) (void);
- void (*func_setup) (void);
+ void (*func_test)(void);
+ void (*func_setup)(void);
} tcases[] = {
{IPC_STAT, func_stat, stat_setup_1},
{IPC_STAT, func_stat, stat_setup_2},
@@ -90,7 +90,7 @@ static void test_hugeshmctl(unsigned int i)
/*
* set_shmat() - Attach the shared memory and return the pointer.
*/
-void *set_shmat(void)
+static void *set_shmat(void)
{
void *rval;
@@ -103,8 +103,8 @@ void *set_shmat(void)
/*
* stat_setup_2() - Set up for the IPC_STAT command with shmctl().
- * Attach the shared memory to parent process and
- * some children will inherit the shared memory.
+ * Attach the shared memory to parent process and
+ * some children will inherit the shared memory.
*/
static void stat_setup_2(void)
{
@@ -139,7 +139,7 @@ static void stat_setup_1(void)
/* now we're back - detach the memory and exit */
if (shmdt(test) == -1)
tst_brk(TBROK | TERRNO,
- "shmdt in stat_setup()");
+ "shmdt in this function broke");
exit(0);
default:
@@ -220,7 +220,8 @@ static void stat_cleanup(void)
/* remove the parent's shared memory if we set*/
if (attach_to_parent) {
if (shmdt(attach_to_parent) == -1)
- tst_res(TFAIL | TERRNO, "shmdt in stat_cleanup()");
+ tst_res(TFAIL | TERRNO,
+ "shmdt in this function failed");
attach_to_parent = NULL;
}
}
@@ -244,7 +245,7 @@ static void func_set(void)
{
/* first stat the shared memory to get the new data */
if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) {
- tst_res(TFAIL | TERRNO, "shmctl in func_set()");
+ tst_res(TFAIL | TERRNO, "shmctl in this function failed");
return;
}
@@ -268,18 +269,18 @@ static void func_rmid(void)
{
/* Do another shmctl() - we should get EINVAL */
if (shmctl(shm_id_1, IPC_STAT, &buf) != -1)
- tst_brk(TBROK, "shmctl in func_rmid() "
+ tst_brk(TBROK, "shmctl in this function "
"succeeded unexpectedly");
if (errno != EINVAL)
- tst_res(TFAIL | TERRNO, "shmctl in func_rmid() failed "
+ tst_res(TFAIL | TERRNO, "shmctl in this function failed "
"unexpectedly - expect errno=EINVAL, got");
else
- tst_res(TPASS, "shmctl in func_rmid() failed as expected, "
+ tst_res(TPASS, "shmctl in this function failed as expected, "
"shared memory appears to be removed");
shm_id_1 = -1;
}
-void setup(void)
+static void setup(void)
{
long hpage_size;
@@ -293,7 +294,7 @@ void setup(void)
shmkey = getipckey();
}
-void cleanup(void)
+static void cleanup(void)
{
rm_shm(shm_id_1);
}
diff --git a/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl02.c b/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl02.c
index 0bc9ffd74..d3f711129 100644
--- a/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl02.c
+++ b/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl02.c
@@ -27,6 +27,7 @@
#include <pwd.h>
#include <limits.h>
#include "hugetlb.h"
+#include "lapi/syscalls.h"
static size_t shm_size;
static int shm_id_1 = -1;
@@ -34,7 +35,7 @@ static int shm_id_2 = -1;
static int shm_id_3 = -1;
static struct shmid_ds buf;
-struct tcase {
+static struct tcase {
int *shmid;
int cmd;
struct shmid_ds *sbuf;
@@ -50,9 +51,37 @@ struct tcase {
{&shm_id_2, -1, &buf, EINVAL},
};
+static int libc_shmctl(int shmid, int cmd, void *buf)
+{
+ return shmctl(shmid, cmd, buf);
+}
+
+static int sys_shmctl(int shmid, int cmd, void *buf)
+{
+ return tst_syscall(__NR_shmctl, shmid, cmd, buf);
+}
+
+static struct test_variants
+{
+ int (*shmctl)(int shmid, int cmd, void *buf);
+ char *desc;
+} variants[] = {
+ { .shmctl = libc_shmctl, .desc = "libc shmctl()"},
+#if (__NR_shmctl != __LTP__NR_INVALID_SYSCALL)
+ { .shmctl = sys_shmctl, .desc = "__NR_shmctl syscall"},
+#endif
+};
+
static void test_hugeshmctl(unsigned int i)
{
- TEST(shmctl(*(tcases[i].shmid), tcases[i].cmd, tcases[i].sbuf));
+ struct test_variants *tv = &variants[tst_variant];
+
+ if (tcases[i].error == EFAULT && tv->shmctl == libc_shmctl) {
+ tst_res(TCONF, "EFAULT is skipped for libc variant");
+ return;
+ }
+
+ TEST(tv->shmctl(*(tcases[i].shmid), tcases[i].cmd, tcases[i].sbuf));
if (TST_RET != -1) {
tst_res(TFAIL, "shmctl succeeded unexpectedly");
return;
@@ -70,8 +99,11 @@ static void test_hugeshmctl(unsigned int i)
static void setup(void)
{
+ struct test_variants *tv = &variants[tst_variant];
long hpage_size;
+ tst_res(TINFO, "Testing variant: %s", tv->desc);
+
if (tst_hugepages == 0)
tst_brk(TCONF, "No enough hugepages for testing.");
@@ -101,6 +133,7 @@ static void cleanup(void)
static struct tst_test test = {
.test = test_hugeshmctl,
+ .test_variants = ARRAY_SIZE(variants),
.tcnt = ARRAY_SIZE(tcases),
.needs_root = 1,
.needs_tmpdir = 1,
diff --git a/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl03.c b/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl03.c
index 21ec6bf78..ec4640686 100644
--- a/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl03.c
+++ b/testcases/kernel/mem/hugetlb/hugeshmctl/hugeshmctl03.c
@@ -41,10 +41,10 @@
static size_t shm_size;
static int shm_id_1 = -1;
static struct shmid_ds buf;
-static uid_t ltp_uid;
-static char *ltp_user = "nobody";
+static uid_t test_uid;
+static char *test_user = "nobody";
-struct tcase {
+static struct tcase {
int *shmid;
int cmd;
struct shmid_ds *sbuf;
@@ -68,7 +68,7 @@ static void test_hugeshmctl(void)
switch (pid = SAFE_FORK()) {
case 0:
/* set the user ID of the child to the non root user */
- SAFE_SETUID(ltp_uid);
+ SAFE_SETUID(test_uid);
do_child();
exit(0);
default:
@@ -97,7 +97,7 @@ static void do_child(void)
}
}
-void setup(void)
+static void setup(void)
{
long hpage_size;
@@ -115,10 +115,10 @@ void setup(void)
tst_brk(TBROK | TERRNO, "shmget");
/* get the userid for a non root user */
- ltp_uid = getuserid(ltp_user);
+ test_uid = getuserid(test_user);
}
-void cleanup(void)
+static void cleanup(void)
{
rm_shm(shm_id_1);
}
diff --git a/testcases/kernel/mem/hugetlb/hugeshmget/hugeshmget03.c b/testcases/kernel/mem/hugetlb/hugeshmget/hugeshmget03.c
index 7e72a19ca..625761f6e 100644
--- a/testcases/kernel/mem/hugetlb/hugeshmget/hugeshmget03.c
+++ b/testcases/kernel/mem/hugetlb/hugeshmget/hugeshmget03.c
@@ -84,7 +84,7 @@ static void cleanup(void)
rm_shm(shm_id_arr[i]);
if (orig_shmmni != -1)
- FILE_PRINTF(PATH_SHMMNI, "%ld", orig_shmmni);
+ SAFE_FILE_PRINTF(PATH_SHMMNI, "%ld", orig_shmmni);
}
static struct tst_test test = {
diff --git a/testcases/kernel/mem/hugetlb/lib/hugetlb.h b/testcases/kernel/mem/hugetlb/lib/hugetlb.h
index 241dab708..34fe08c24 100644
--- a/testcases/kernel/mem/hugetlb/lib/hugetlb.h
+++ b/testcases/kernel/mem/hugetlb/lib/hugetlb.h
@@ -39,6 +39,12 @@
# endif
#endif
+/* Check if hugetlb page is gigantic */
+static inline int is_hugetlb_gigantic(unsigned long hpage_size)
+{
+ return (hpage_size / getpagesize()) >> 11;
+}
+
/*
* to get the lower nine permission bits
* from shmid_ds.ipc_perm.mode
diff --git a/testcases/kernel/mem/include/mem.h b/testcases/kernel/mem/include/mem.h
index 776809113..cdc3ca146 100644
--- a/testcases/kernel/mem/include/mem.h
+++ b/testcases/kernel/mem/include/mem.h
@@ -42,7 +42,6 @@ static inline void clean_node(unsigned long *array)
#define MLOCK 2
#define KSM 3
-extern long overcommit;
void oom(int testcase, int lite, int retcode, int allow_sigkill);
void testoom(int mempolicy, int lite, int retcode, int allow_sigkill);
diff --git a/testcases/kernel/mem/ksm/ksm05.c b/testcases/kernel/mem/ksm/ksm05.c
index 25f3435b2..1f58c8325 100644
--- a/testcases/kernel/mem/ksm/ksm05.c
+++ b/testcases/kernel/mem/ksm/ksm05.c
@@ -95,6 +95,10 @@ static struct tst_test test = {
"CONFIG_KSM=y",
NULL
},
+ .tags = (const struct tst_tag[]) {
+ {"CVE", "2011-2183"},
+ {}
+ }
};
#else
diff --git a/testcases/kernel/mem/lib/mem.c b/testcases/kernel/mem/lib/mem.c
index 8ddd7adf7..fbfeef026 100644
--- a/testcases/kernel/mem/lib/mem.c
+++ b/testcases/kernel/mem/lib/mem.c
@@ -27,8 +27,6 @@
/* OOM */
-long overcommit = -1;
-
static int alloc_mem(long int length, int testcase)
{
char *s;
diff --git a/testcases/kernel/mem/oom/oom01.c b/testcases/kernel/mem/oom/oom01.c
index 9f7d76587..b13699898 100644
--- a/testcases/kernel/mem/oom/oom01.c
+++ b/testcases/kernel/mem/oom/oom01.c
@@ -49,22 +49,13 @@ static void verify_oom(void)
testoom(0, 0, ENOMEM, 1);
}
-static void setup(void)
-{
- overcommit = get_sys_tune("overcommit_memory");
-}
-
-static void cleanup(void)
-{
- if (overcommit != -1)
- set_sys_tune("overcommit_memory", overcommit, 0);
-}
-
static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
.max_runtime = TST_UNLIMITED_RUNTIME,
- .setup = setup,
- .cleanup = cleanup,
.test_all = verify_oom,
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", NULL, TST_SR_TBROK},
+ {}
+ },
};
diff --git a/testcases/kernel/mem/oom/oom02.c b/testcases/kernel/mem/oom/oom02.c
index b3719f723..8d565d12a 100644
--- a/testcases/kernel/mem/oom/oom02.c
+++ b/testcases/kernel/mem/oom/oom02.c
@@ -56,15 +56,6 @@ static void setup(void)
{
if (!is_numa(NULL, NH_MEMS, 2))
tst_brk(TCONF, "The case need a NUMA system.");
-
- overcommit = get_sys_tune("overcommit_memory");
- set_sys_tune("overcommit_memory", 1, 1);
-}
-
-static void cleanup(void)
-{
- if (overcommit != -1)
- set_sys_tune("overcommit_memory", overcommit, 0);
}
static struct tst_test test = {
@@ -72,8 +63,11 @@ static struct tst_test test = {
.forks_child = 1,
.max_runtime = TST_UNLIMITED_RUNTIME,
.setup = setup,
- .cleanup = cleanup,
.test_all = verify_oom,
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", "1", TST_SR_TBROK},
+ {}
+ },
};
#else
diff --git a/testcases/kernel/mem/oom/oom03.c b/testcases/kernel/mem/oom/oom03.c
index 0882c9bbe..778055d03 100644
--- a/testcases/kernel/mem/oom/oom03.c
+++ b/testcases/kernel/mem/oom/oom03.c
@@ -79,27 +79,21 @@ static void verify_oom(void)
static void setup(void)
{
- overcommit = get_sys_tune("overcommit_memory");
- set_sys_tune("overcommit_memory", 1, 1);
-
SAFE_CG_PRINTF(tst_cg, "cgroup.procs", "%d", getpid());
SAFE_CG_PRINTF(tst_cg, "memory.max", "%lu", TESTMEM);
}
-static void cleanup(void)
-{
- if (overcommit != -1)
- set_sys_tune("overcommit_memory", overcommit, 0);
-}
-
static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
.max_runtime = TST_UNLIMITED_RUNTIME,
.setup = setup,
- .cleanup = cleanup,
.test_all = verify_oom,
.needs_cgroup_ctrls = (const char *const []){ "memory", NULL },
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", "1", TST_SR_TBROK},
+ {}
+ },
};
#else
diff --git a/testcases/kernel/mem/oom/oom04.c b/testcases/kernel/mem/oom/oom04.c
index ad39f7e77..d27d9d9e7 100644
--- a/testcases/kernel/mem/oom/oom04.c
+++ b/testcases/kernel/mem/oom/oom04.c
@@ -65,9 +65,6 @@ static void setup(void)
if (!is_numa(NULL, NH_MEMS, 1))
tst_brk(TCONF, "requires NUMA with at least 1 node");
- overcommit = get_sys_tune("overcommit_memory");
- set_sys_tune("overcommit_memory", 1, 1);
-
/*
* Some nodes do not contain memory, so use
* get_allowed_nodes(NH_MEMS) to get a memory
@@ -82,20 +79,17 @@ static void setup(void)
SAFE_CG_PRINTF(tst_cg, "cgroup.procs", "%d", getpid());
}
-static void cleanup(void)
-{
- if (overcommit != -1)
- set_sys_tune("overcommit_memory", overcommit, 0);
-}
-
static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
.max_runtime = TST_UNLIMITED_RUNTIME,
.setup = setup,
- .cleanup = cleanup,
.test_all = verify_oom,
.needs_cgroup_ctrls = (const char *const []){ "cpuset", NULL },
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", "1", TST_SR_TBROK},
+ {}
+ },
};
#else
diff --git a/testcases/kernel/mem/oom/oom05.c b/testcases/kernel/mem/oom/oom05.c
index e31146e7a..eb1a64267 100644
--- a/testcases/kernel/mem/oom/oom05.c
+++ b/testcases/kernel/mem/oom/oom05.c
@@ -85,9 +85,6 @@ void setup(void)
if (!is_numa(NULL, NH_MEMS, 1))
tst_brk(TCONF, "requires NUMA with at least 1 node");
- overcommit = get_sys_tune("overcommit_memory");
- set_sys_tune("overcommit_memory", 1, 1);
-
/*
* Some nodes do not contain memory, so use
* get_allowed_nodes(NH_MEMS) to get a memory
@@ -104,22 +101,19 @@ void setup(void)
SAFE_CG_PRINTF(tst_cg, "memory.max", "%lu", TESTMEM);
}
-void cleanup(void)
-{
- if (overcommit != -1)
- set_sys_tune("overcommit_memory", overcommit, 0);
-}
-
static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
.max_runtime = TST_UNLIMITED_RUNTIME,
.setup = setup,
- .cleanup = cleanup,
.test_all = verify_oom,
.needs_cgroup_ctrls = (const char *const []){
"memory", "cpuset", NULL
},
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", "1", TST_SR_TBROK},
+ {}
+ },
};
#else
diff --git a/testcases/kernel/mem/thp/thp03.c b/testcases/kernel/mem/thp/thp03.c
index c6062505f..839efcb0e 100644
--- a/testcases/kernel/mem/thp/thp03.c
+++ b/testcases/kernel/mem/thp/thp03.c
@@ -30,7 +30,6 @@
* corruption and no data corruption (nor userland nor kernel).
*/
-#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
diff --git a/testcases/kernel/mem/thp/thp04.c b/testcases/kernel/mem/thp/thp04.c
index 7cab5d76b..b5f518ac5 100644
--- a/testcases/kernel/mem/thp/thp04.c
+++ b/testcases/kernel/mem/thp/thp04.c
@@ -26,8 +26,6 @@
* commit 8310d48b125d("huge_memory.c: respect FOLL_FORCE/FOLL_COW for thp").
*/
-#include <sys/mman.h>
-
#include "tst_test.h"
#include "lapi/mmap.h"
#include "tst_fuzzy_sync.h"
diff --git a/testcases/kernel/mem/tunable/max_map_count.c b/testcases/kernel/mem/tunable/max_map_count.c
index caf8972e0..f33095473 100644
--- a/testcases/kernel/mem/tunable/max_map_count.c
+++ b/testcases/kernel/mem/tunable/max_map_count.c
@@ -53,26 +53,6 @@
#define MAP_COUNT_DEFAULT 1024
#define MAX_MAP_COUNT 65536L
-static long old_max_map_count = -1;
-static long old_overcommit = -1;
-
-static void setup(void)
-{
- SAFE_ACCESS(PATH_SYSVM "max_map_count", F_OK);
-
- old_max_map_count = get_sys_tune("max_map_count");
- old_overcommit = get_sys_tune("overcommit_memory");
- set_sys_tune("overcommit_memory", 0, 1);
-}
-
-static void cleanup(void)
-{
- if (old_overcommit != -1)
- set_sys_tune("overcommit_memory", old_overcommit, 0);
- if (old_max_map_count != -1)
- set_sys_tune("max_map_count", old_max_map_count, 0);
-}
-
/* This is a filter to exclude map entries which aren't accounted
* for in the vm_area_struct's map_count.
*/
@@ -210,7 +190,10 @@ static void max_map_count_test(void)
static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
- .setup = setup,
- .cleanup = cleanup,
.test_all = max_map_count_test,
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", "0", TST_SR_TBROK},
+ {"/proc/sys/vm/max_map_count", NULL, TST_SR_TBROK},
+ {}
+ },
};
diff --git a/testcases/kernel/mem/tunable/min_free_kbytes.c b/testcases/kernel/mem/tunable/min_free_kbytes.c
index eab6c8b2e..19da409e8 100644
--- a/testcases/kernel/mem/tunable/min_free_kbytes.c
+++ b/testcases/kernel/mem/tunable/min_free_kbytes.c
@@ -41,7 +41,6 @@
volatile int end;
static long default_tune = -1;
-static long orig_overcommit = -1;
static unsigned long total_mem;
static void test_tune(unsigned long overcommit_policy);
@@ -217,15 +216,6 @@ static void setup(void)
total_mem = SAFE_READ_MEMINFO("MemTotal:") + SAFE_READ_MEMINFO("SwapTotal:");
default_tune = get_sys_tune("min_free_kbytes");
- orig_overcommit = get_sys_tune("overcommit_memory");
-}
-
-static void cleanup(void)
-{
- if (default_tune != -1)
- set_sys_tune("min_free_kbytes", default_tune, 0);
- if (orig_overcommit != -1)
- set_sys_tune("overcommit_memory", orig_overcommit, 0);
}
static struct tst_test test = {
@@ -233,6 +223,10 @@ static struct tst_test test = {
.forks_child = 1,
.max_runtime = TST_UNLIMITED_RUNTIME,
.setup = setup,
- .cleanup = cleanup,
.test_all = min_free_kbytes_test,
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", NULL, TST_SR_TBROK},
+ {"/proc/sys/vm/min_free_kbytes", NULL, TST_SR_TBROK},
+ {}
+ },
};
diff --git a/testcases/kernel/mem/tunable/overcommit_memory.c b/testcases/kernel/mem/tunable/overcommit_memory.c
index 7fe8fe14c..ffb7a6d9d 100644
--- a/testcases/kernel/mem/tunable/overcommit_memory.c
+++ b/testcases/kernel/mem/tunable/overcommit_memory.c
@@ -70,7 +70,6 @@
#define EXPECT_FAIL 1
static char *R_opt;
-static long old_overcommit_memory = -1;
static long old_overcommit_ratio = -1;
static long overcommit_ratio;
static long sum_total;
@@ -90,16 +89,11 @@ static void setup(void)
long mem_total, swap_total;
struct rlimit lim;
- if (access(PATH_SYSVM "overcommit_memory", F_OK) == -1 ||
- access(PATH_SYSVM "overcommit_ratio", F_OK) == -1)
- tst_brk(TCONF, "system doesn't support overcommit_memory");
-
if (R_opt)
overcommit_ratio = SAFE_STRTOL(R_opt, 0, LONG_MAX);
else
overcommit_ratio = DEFAULT_OVER_RATIO;
- old_overcommit_memory = get_sys_tune("overcommit_memory");
old_overcommit_ratio = get_sys_tune("overcommit_ratio");
mem_total = SAFE_READ_MEMINFO("MemTotal:");
@@ -128,14 +122,6 @@ static void setup(void)
tst_res(TINFO, "TotalBatchSize is %ld kB", total_batch_size);
}
-static void cleanup(void)
-{
- if (old_overcommit_memory != -1)
- set_sys_tune("overcommit_memory", old_overcommit_memory, 0);
- if (old_overcommit_ratio != -1)
- set_sys_tune("overcommit_ratio", old_overcommit_ratio, 0);
-}
-
static void overcommit_memory_test(void)
{
@@ -269,6 +255,10 @@ static struct tst_test test = {
{}
},
.setup = setup,
- .cleanup = cleanup,
.test_all = overcommit_memory_test,
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/vm/overcommit_memory", NULL, TST_SR_TBROK},
+ {"/proc/sys/vm/overcommit_ratio", NULL, TST_SR_TBROK},
+ {}
+ },
};
diff --git a/testcases/kernel/mem/vma/vma05.sh b/testcases/kernel/mem/vma/vma05.sh
index 9ef6f0a23..c9e4becdb 100755
--- a/testcases/kernel/mem/vma/vma05.sh
+++ b/testcases/kernel/mem/vma/vma05.sh
@@ -30,6 +30,7 @@ setup()
{
ulimit -c unlimited
echo "core" > /proc/sys/kernel/core_pattern
+ unset DEBUGINFOD_URLS
}
cleanup()
diff --git a/testcases/kernel/numa/numa01.sh b/testcases/kernel/numa/numa01.sh
index 367813ce9..0181cd8f5 100755
--- a/testcases/kernel/numa/numa01.sh
+++ b/testcases/kernel/numa/numa01.sh
@@ -183,7 +183,7 @@ test4()
no_of_cpus=$(tst_ncpus)
# not sure whether cpu's can't be in odd number
run_on_cpu=$(($((no_of_cpus+1))/2))
- numactl --physcpubind=$run_on_cpu support_numa pause & #just waits for sigint
+ numactl --all --physcpubind=$run_on_cpu support_numa pause & #just waits for sigint
pid=$!
var=`awk '{ print $2 }' /proc/$pid/stat`
while [ $var = '(numactl)' ]; do
diff --git a/testcases/kernel/numa/support_numa.c b/testcases/kernel/numa/support_numa.c
index a0afee554..6fb82f374 100644
--- a/testcases/kernel/numa/support_numa.c
+++ b/testcases/kernel/numa/support_numa.c
@@ -37,7 +37,6 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/mman.h>
#include <fcntl.h>
#include "lapi/mmap.h"
diff --git a/testcases/kernel/sched/cfs-scheduler/.gitignore b/testcases/kernel/sched/cfs-scheduler/.gitignore
index c5dacd6ef..3ea3f75fc 100644
--- a/testcases/kernel/sched/cfs-scheduler/.gitignore
+++ b/testcases/kernel/sched/cfs-scheduler/.gitignore
@@ -1,2 +1,3 @@
/hackbench
-cfs_bandwidth01
+/cfs_bandwidth01
+/starvation
diff --git a/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c b/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
index 8f2da4493..27fc0fc5d 100644
--- a/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
+++ b/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-/* Copyright (c) 2021 SUSE LLC <rpalethorpe@suse.com> */
+/*
+ * Copyright (c) 2021 SUSE LLC <rpalethorpe@suse.com>
+ * Copyright (c) Linux Test Project, 2021-2023
+ */
+
/*\
- *
* [Description]
*
* Creates a multi-level CGroup hierarchy with the cpu controller
@@ -15,7 +18,8 @@
* them to be unthrottle.
*
* The test is known to reproduce an issue with an update to
- * SLE-15-SP1 (kernel 4.12.14-197.64, bsc#1179093).
+ * SLE-15-SP1 (kernel 4.12.14-197.64,
+ * https://bugzilla.suse.com/show_bug.cgi?id=1179093).
*
* Also as an reproducer for another bug:
*
diff --git a/testcases/kernel/sched/cfs-scheduler/starvation.c b/testcases/kernel/sched/cfs-scheduler/starvation.c
new file mode 100644
index 000000000..eb9fd6ff5
--- /dev/null
+++ b/testcases/kernel/sched/cfs-scheduler/starvation.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright 2023 Mike Galbraith <efault-AT-gmx.de> */
+/* Copyright 2023 Wei Gao <wegao@suse.com> */
+/*\
+ *
+ * [Description]
+ *
+ * Thread starvation test. On fauluty kernel the test timeouts.
+ *
+ * Original reproducer taken from:
+ * https://lore.kernel.org/lkml/9fd2c37a05713c206dcbd5866f67ce779f315e9e.camel@gmx.de/
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <sched.h>
+
+#include "tst_test.h"
+
+static char *str_loop;
+static long loop = 2000000;
+static char *str_timeout;
+static int timeout = 240;
+
+static int wait_for_pid(pid_t pid)
+{
+ int status, ret;
+
+again:
+ ret = waitpid(pid, &status, 0);
+ if (ret == -1) {
+ if (errno == EINTR)
+ goto again;
+
+ return -1;
+ }
+
+ if (WIFSIGNALED(status))
+ return 0;
+
+ return -1;
+}
+
+static void setup(void)
+{
+ cpu_set_t mask;
+
+ CPU_ZERO(&mask);
+
+ CPU_SET(0, &mask);
+
+ TST_EXP_POSITIVE(sched_setaffinity(0, sizeof(mask), &mask));
+
+ if (tst_parse_long(str_loop, &loop, 1, LONG_MAX))
+ tst_brk(TBROK, "Invalid number of loop number '%s'", str_loop);
+
+ if (tst_parse_int(str_timeout, &timeout, 1, INT_MAX))
+ tst_brk(TBROK, "Invalid number of timeout '%s'", str_timeout);
+
+ tst_set_max_runtime(timeout);
+}
+
+static void handler(int sig LTP_ATTRIBUTE_UNUSED)
+{
+ if (loop > 0)
+ --loop;
+}
+
+static void child(void)
+{
+ pid_t ppid = getppid();
+
+ TST_CHECKPOINT_WAIT(0);
+
+ while (1)
+ SAFE_KILL(ppid, SIGUSR1);
+}
+
+static void do_test(void)
+{
+ pid_t child_pid;
+
+ child_pid = SAFE_FORK();
+
+ if (!child_pid)
+ child();
+
+ SAFE_SIGNAL(SIGUSR1, handler);
+ TST_CHECKPOINT_WAKE(0);
+
+ while (loop)
+ sleep(1);
+
+ SAFE_KILL(child_pid, SIGTERM);
+ TST_EXP_PASS(wait_for_pid(child_pid));
+}
+
+static struct tst_test test = {
+ .test_all = do_test,
+ .setup = setup,
+ .forks_child = 1,
+ .options = (struct tst_option[]) {
+ {"l:", &str_loop, "Number of loops (default 2000000)"},
+ {"t:", &str_timeout, "Max timeout (default 240s)"},
+ {}
+ },
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c b/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c
index 9c2b03994..2a982347c 100644
--- a/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c
+++ b/testcases/kernel/security/dirtyc0w_shmem/dirtyc0w_shmem_child.c
@@ -115,7 +115,7 @@ static void *uffd_thread_fn(void *arg)
if (ioctl(uffd, UFFDIO_CONTINUE, &uffdio) < 0) {
if (errno == EEXIST) {
uffdio_wake.start = (unsigned long) map;
- uffdio_wake.len = 4096;
+ uffdio_wake.len = page_size;
SAFE_IOCTL(uffd, UFFDIO_WAKE, &uffdio_wake);
}
}
diff --git a/testcases/kernel/security/tomoyo/.gitignore b/testcases/kernel/security/tomoyo/.gitignore
deleted file mode 100644
index 698646d93..000000000
--- a/testcases/kernel/security/tomoyo/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-/newns
-/tomoyo_accept_test
-/tomoyo_file_test
-/tomoyo_filesystem_test
-/tomoyo_new_file_test
-/tomoyo_new_test
-/tomoyo_policy_io_test
-/tomoyo_policy_memory_test
-/tomoyo_rewrite_test
diff --git a/testcases/kernel/security/tomoyo/Makefile b/testcases/kernel/security/tomoyo/Makefile
deleted file mode 100644
index 00e4cc3ed..000000000
--- a/testcases/kernel/security/tomoyo/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# kernel/security/smack testcase Makefile
-#
-# Copyright (C) 2009, Cisco Systems 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Ngie Cooper, July 2009
-#
-
-top_srcdir ?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-INSTALL_TARGETS := testall.sh
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/security/tomoyo/README b/testcases/kernel/security/tomoyo/README
deleted file mode 100644
index 0cb538868..000000000
--- a/testcases/kernel/security/tomoyo/README
+++ /dev/null
@@ -1,58 +0,0 @@
-Always look here for latest version of these tests:
-http://sourceforge.jp/projects/tomoyo/svn/view/trunk/2.3.x/tomoyo-tools/kernel_test/?root=tomoyo
-
-These testcases test the TOMOYO Security Module. And they are not part of
-default LTP build/install/run.
-
-A kernel with TOMOYO configured is required to run the TOMOYO testsuite.
-The securityfs filesystem must be mounted at /sys/kernel/security .
-
-Preparation steps are:
-
-1) Download tomoyo-tools package and extract and build and install.
-
- # wget -O tomoyo-tools.tar.gz 'http://sourceforge.jp/projects/tomoyo/svn/view/trunk/2.3.x/tomoyo-tools.tar.gz?root=tomoyo&view=tar'
- # tar -zxf tomoyo-tools.tar.gz
- # make -C tomoyo-tools/ install
-
- Programs are installed in /usr/sbin/ with prefix "tomoyo-" and
- /usr/lib/tomoyo/ directory without prefix "tomoyo-".
-
- You can make a RPM package by "rpmbuild -bb tomoyo-tools/tomoyo-tools.spec" and
- a DEB package by "alien -k" after "rpmbuild -bb".
-
-2) Run /usr/lib/tomoyo/init_policy .
-
- This will take several minutes.
-
- Hiding kernel source directory by "mount -t tmpfs none /usr/src/linux/"
- would save some time.
-
- Configuration files are saved in /etc/tomoyo/ directory.
- You can do "rm -fR /etc/tomoyo/" if you want to uninstall.
-
-3) Reboot the system with TOMOYO enabled kernel.
-
- To make sure TOMOYO is selected, you can add security=tomoyo to kernel's
- command line.
-
-4) Build the tests.
-
- # (extract the tar ball containing the tests.)
- # make autotools
- # ./configure
- # cd testcases/kernel/security/tomoyo/
- # make
- # find `/bin/pwd` -type f -perm +100 >> /etc/tomoyo/manager.conf
- # /usr/sbin/tomoyo-loadpolicy m
-
-Test steps are:
-
-1) Run the tests from the directory you ran "make".
-
- # ./testall.sh
-
- Please don't run the tests inside /tmp/ directory, for /tmp/ directory is
- hidden by "newns" (a wrapper program to run the test in a new namespace).
-
- You can use "| grep -vF OK" to pick up only failed tests as testall.sh does.
diff --git a/testcases/kernel/security/tomoyo/include.h b/testcases/kernel/security/tomoyo/include.h
deleted file mode 100644
index edaf1170f..000000000
--- a/testcases/kernel/security/tomoyo/include.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/******************************************************************************/
-/* */
-/* Copyright (c) Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>, 2009 */
-/* */
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * include.h
- *
- * Common functions for testing TOMOYO Linux's kernel.
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/kdev_t.h>
-#include <linux/unistd.h>
-#include <pty.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <sys/timex.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <time.h>
-#include <unistd.h>
-#include <utime.h>
-#include <sched.h>
-#include <stdarg.h>
-#include <sys/mount.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <linux/ip.h>
-#include <err.h>
-#include "test.h"
-
-/*
- * Some architectures like mips n32 don't have __NR_uselib defined in the
- * system headers.
- */
-#ifdef __NR_uselib
-static inline int uselib(const char *library)
-{
- return syscall(__NR_uselib, library);
-}
-#else
-static inline int uselib(const char *library)
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-/* Is there an architecture without __NR_pivot_root defined? */
-#ifdef __NR_pivot_root
-static inline int pivot_root(const char *new_root, const char *put_old)
-{
- return syscall(__NR_pivot_root, new_root, put_old);
-}
-#else
-static inline int pivot_root(const char *new_root, const char *put_old)
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-/* The sysctl() wrapper is dead and newer arches omit it now. */
-static inline int write_sysctl(const char *path, const char *value)
-{
- FILE *fp = fopen(path, "w");
- if (!fp)
- return 1;
- fputs(value, fp);
- fclose(fp);
- return 0;
-}
-
-static inline int read_sysctl(const char *path, char *value, int len)
-{
- char scratch[100];
- FILE *fp = fopen(path, "r");
- if (!fp)
- return 1;
- if (!value) {
- value = scratch;
- len = sizeof(scratch);
- }
- if (fgets(value, len, fp))
- /* ignore */;
- fclose(fp);
- return 0;
-}
-
-/* Should be a fairly benign path to bang on. */
-#define TEST_SYSCTL_PATH "/proc/sys/net/ipv4/ip_local_port_range"
-
-#define proc_policy_dir "/sys/kernel/security/tomoyo/"
-#define proc_policy_domain_policy "/sys/kernel/security/tomoyo/domain_policy"
-#define proc_policy_exception_policy "/sys/kernel/security/tomoyo/exception_policy"
-#define proc_policy_profile "/sys/kernel/security/tomoyo/profile"
-#define proc_policy_manager "/sys/kernel/security/tomoyo/manager"
-#define proc_policy_query "/sys/kernel/security/tomoyo/query"
-#define proc_policy_grant_log "/sys/kernel/security/tomoyo/grant_log"
-#define proc_policy_reject_log "/sys/kernel/security/tomoyo/reject_log"
-#define proc_policy_domain_status "/sys/kernel/security/tomoyo/.domain_status"
-#define proc_policy_process_status "/sys/kernel/security/tomoyo/.process_status"
-#define proc_policy_self_domain "/sys/kernel/security/tomoyo/self_domain"
-
-static FILE *profile_fp = NULL;
-static FILE *domain_fp = NULL;
-static FILE *exception_fp = NULL;
-static char self_domain[4096] = "";
-static pid_t pid = 0;
-
-static void clear_status(void)
-{
- static const char *keywords[] = {
- "file::execute",
- "file::open",
- "file::create",
- "file::unlink",
- "file::mkdir",
- "file::rmdir",
- "file::mkfifo",
- "file::mksock",
- "file::truncate",
- "file::symlink",
- "file::rewrite",
- "file::mkblock",
- "file::mkchar",
- "file::link",
- "file::rename",
- "file::chmod",
- "file::chown",
- "file::chgrp",
- "file::ioctl",
- "file::chroot",
- "file::mount",
- "file::umount",
- "file::pivot_root",
- NULL
- };
- int i;
- FILE *fp = fopen(proc_policy_profile, "r");
- static char buffer[4096];
- if (!fp) {
- fprintf(stderr, "Can't open %s\n", proc_policy_profile);
- exit(1);
- }
- for (i = 0; keywords[i]; i++)
- fprintf(profile_fp,
- "255-CONFIG::%s={ mode=disabled }\n",
- keywords[i]);
- while (memset(buffer, 0, sizeof(buffer)),
- fgets(buffer, sizeof(buffer) - 10, fp)) {
- const char *mode;
- char *cp = strchr(buffer, '=');
- if (!cp)
- continue;
- *cp = '\0';
- mode = cp + 1;
- cp = strchr(buffer, '-');
- if (!cp)
- continue;
- *cp++ = '\0';
- if (strcmp(buffer, "0"))
- continue;
- fprintf(profile_fp, "255-%s", cp);
- if (!strcmp(cp, "COMMENT"))
- mode = "Profile for kernel test\n";
- else
- mode = "{ mode=disabled verbose=no }\n";
- fprintf(profile_fp, "255-%s=%s", cp, mode);
- }
- fprintf(profile_fp, "255-PREFERENCE::learning= verbose=no\n");
- fprintf(profile_fp, "255-PREFERENCE::enforcing= verbose=no\n");
- fprintf(profile_fp, "255-PREFERENCE::permissive= verbose=no\n");
- fprintf(profile_fp, "255-PREFERENCE::disabled= verbose=no\n");
- fprintf(profile_fp, "255-PREFERENCE::learning= max_entry=2048\n");
- fflush(profile_fp);
- fclose(fp);
-}
-
-static void tomoyo_test_init(void)
-{
- pid = getpid();
- if (access(proc_policy_dir, F_OK)) {
- fprintf(stderr, "You can't use this program for this kernel."
- "\n");
- exit(1);
- }
- profile_fp = fopen(proc_policy_profile, "w");
- if (!profile_fp) {
- fprintf(stderr, "Can't open %s .\n", proc_policy_profile);
- exit(1);
- }
- setlinebuf(profile_fp);
- domain_fp = fopen(proc_policy_domain_policy, "w");
- if (!domain_fp) {
- fprintf(stderr, "Can't open %s .\n",
- proc_policy_domain_policy);
- exit(1);
- }
- setlinebuf(domain_fp);
- exception_fp = fopen(proc_policy_exception_policy, "w");
- if (!exception_fp) {
- fprintf(stderr, "Can't open %s .\n",
- proc_policy_exception_policy);
- exit(1);
- }
- setlinebuf(exception_fp);
- if (fputc('\n', profile_fp) != '\n' || fflush(profile_fp)) {
- fprintf(stderr, "You need to register this program to %s to "
- "run this program.\n", proc_policy_manager);
- exit(1);
- }
- clear_status();
- {
- FILE *fp = fopen(proc_policy_self_domain, "r");
- memset(self_domain, 0, sizeof(self_domain));
- if (!fp || !fgets(self_domain, sizeof(self_domain) - 1, fp) ||
- fclose(fp)) {
- fprintf(stderr, "Can't open %s .\n",
- proc_policy_self_domain);
- exit(1);
- }
- }
- fprintf(domain_fp, "select pid=%u\n", pid);
- fprintf(domain_fp, "use_profile 255\n");
- fprintf(domain_fp, "allow_read/write /sys/kernel/security/tomoyo/domain_policy\n");
- fprintf(domain_fp, "allow_truncate /sys/kernel/security/tomoyo/domain_policy\n");
- fprintf(domain_fp, "allow_read/write /sys/kernel/security/tomoyo/exception_policy\n");
- fprintf(domain_fp, "allow_truncate /sys/kernel/security/tomoyo/exception_policy\n");
- fprintf(domain_fp, "allow_read/write /sys/kernel/security/tomoyo/profile\n");
- fprintf(domain_fp, "allow_truncate /sys/kernel/security/tomoyo/profile\n");
-}
-
-static void BUG(const char *fmt, ...)
- __attribute__ ((format(printf, 1, 2)));
-
-static void BUG(const char *fmt, ...)
-{
- va_list args;
- printf("BUG: ");
- va_start(args, fmt);
- vprintf(fmt, args);
- va_end(args);
- putchar('\n');
- fflush(stdout);
- while (1)
- sleep(100);
-}
-
-int write_domain_policy(const char *policy, int is_delete)
-{
- FILE *fp = fopen(proc_policy_domain_policy, "r");
- char buffer[8192];
- int domain_found = 0;
- int policy_found = 0;
- memset(buffer, 0, sizeof(buffer));
- if (!fp) {
- BUG("Can't read %s", proc_policy_domain_policy);
- return 0;
- }
- if (is_delete)
- fprintf(domain_fp, "delete ");
- fprintf(domain_fp, "%s\n", policy);
- while (fgets(buffer, sizeof(buffer) - 1, fp)) {
- char *cp = strchr(buffer, '\n');
- if (cp)
- *cp = '\0';
- if (!strncmp(buffer, "<kernel>", 8))
- domain_found = !strcmp(self_domain, buffer);
- if (!domain_found)
- continue;
- /* printf("<%s>\n", buffer); */
- if (strcmp(buffer, policy))
- continue;
- policy_found = 1;
- break;
- }
- fclose(fp);
- if (policy_found == is_delete) {
- BUG("Can't %s %s", is_delete ? "delete" : "append",
- policy);
- return 0;
- }
- errno = 0;
- return 1;
-
-}
-
-int write_exception_policy(const char *policy, int is_delete)
-{
- FILE *fp = fopen(proc_policy_exception_policy, "r");
- char buffer[8192];
- int policy_found = 0;
- memset(buffer, 0, sizeof(buffer));
- if (!fp) {
- BUG("Can't read %s", proc_policy_exception_policy);
- return 0;
- }
- if (is_delete)
- fprintf(exception_fp, "delete ");
- fprintf(exception_fp, "%s\n", policy);
- while (fgets(buffer, sizeof(buffer) - 1, fp)) {
- char *cp = strchr(buffer, '\n');
- if (cp)
- *cp = '\0';
- if (strcmp(buffer, policy))
- continue;
- policy_found = 1;
- break;
- }
- fclose(fp);
- if (policy_found == is_delete) {
- BUG("Can't %s %s", is_delete ? "delete" : "append",
- policy);
- return 0;
- }
- errno = 0;
- return 1;
-
-}
-
-int set_profile(const int mode, const char *name)
-{
- static const char *modes[4] = { "disabled", "learning", "permissive",
- "enforcing" };
- FILE *fp = fopen(proc_policy_profile, "r");
- char buffer[8192];
- int policy_found = 0;
- const int len = strlen(name);
- if (!fp) {
- BUG("Can't read %s", proc_policy_profile);
- return 0;
- }
- fprintf(profile_fp, "255-CONFIG::%s=%s\n", name, modes[mode]);
- while (memset(buffer, 0, sizeof(buffer)),
- fgets(buffer, sizeof(buffer) - 1, fp)) {
- char *cp = strchr(buffer, '\n');
- if (cp)
- *cp = '\0';
- if (strncmp(buffer, "255-CONFIG::", 12) ||
- strncmp(buffer + 12, name, len) ||
- buffer[12 + len] != '=')
- continue;
- if (strstr(buffer + 13 + len, modes[mode]))
- policy_found = 1;
- break;
- }
- fclose(fp);
- if (!policy_found) {
- BUG("Can't change profile to 255-CONFIG::%s=%s",
- name, modes[mode]);
- return 0;
- }
- errno = 0;
- return 1;
-}
diff --git a/testcases/kernel/security/tomoyo/newns.c b/testcases/kernel/security/tomoyo/newns.c
deleted file mode 100644
index f888ca31f..000000000
--- a/testcases/kernel/security/tomoyo/newns.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/******************************************************************************/
-/* */
-/* Copyright (c) Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>, 2009 */
-/* */
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/mount.h>
-#include <unistd.h>
-#include <sched.h>
-#include <errno.h>
-#include <stdlib.h>
-#include "test.h"
-
-static int child(void *arg)
-{
- char **argv = (char **)arg;
- argv++;
- mount("/tmp/", "/tmp/", "tmpfs", 0, NULL);
- execvp(argv[0], argv);
- _exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- char c = 0;
- const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child, (void *)argv);
- while (waitpid(pid, NULL, __WALL) == EOF && errno == EINTR)
- c++; /* Dummy. */
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/testall.sh b/testcases/kernel/security/tomoyo/testall.sh
deleted file mode 100644
index b103be6c6..000000000
--- a/testcases/kernel/security/tomoyo/testall.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#! /bin/sh
-################################################################################
-## ##
-## Copyright (c) Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>, 2009 ##
-## ##
-## 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, write to the Free Software ##
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ##
-## ##
-################################################################################
-
-cd ${0%/*}
-export PATH=$PWD:${PATH}
-
-echo "Testing all. (All results are reported)"
-newns tomoyo_accept_test
-newns tomoyo_filesystem_test
-newns tomoyo_file_test
-newns tomoyo_rewrite_test
-newns tomoyo_new_file_test
-newns tomoyo_new_test
-echo
-echo
-echo
-echo "Testing all. (Only ERRORS are reported)"
-newns tomoyo_accept_test | grep -vF Done
-newns tomoyo_filesystem_test | grep -vF OK | grep -F '('
-newns tomoyo_file_test | grep -vF OK | grep -F '('
-newns tomoyo_rewrite_test | grep -vF OK | grep -F '('
-newns tomoyo_new_test | grep -vF OK
-echo
-echo
-echo
-echo "Testing policy I/O. (Only ERRORS are reported)"
-newns tomoyo_policy_io_test | grep -vF OK
-newns tomoyo_new_file_test | grep -vF OK
diff --git a/testcases/kernel/security/tomoyo/tomoyo_accept_test.c b/testcases/kernel/security/tomoyo/tomoyo_accept_test.c
deleted file mode 100644
index 335818a25..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_accept_test.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_accept_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#include "include.h"
-
-static void set_level(const int i)
-{
- set_profile(i, "file::execute");
- set_profile(i, "file::open");
- set_profile(i, "file::create");
- set_profile(i, "file::unlink");
- set_profile(i, "file::mkdir");
- set_profile(i, "file::rmdir");
- set_profile(i, "file::mkfifo");
- set_profile(i, "file::mksock");
- set_profile(i, "file::truncate");
- set_profile(i, "file::symlink");
- set_profile(i, "file::rewrite");
- set_profile(i, "file::mkblock");
- set_profile(i, "file::mkchar");
- set_profile(i, "file::link");
- set_profile(i, "file::rename");
- set_profile(i, "file::chmod");
- set_profile(i, "file::chown");
- set_profile(i, "file::chgrp");
- set_profile(i, "file::ioctl");
- set_profile(i, "file::chroot");
- set_profile(i, "file::mount");
- set_profile(i, "file::umount");
- set_profile(i, "file::pivot_root");
-}
-
-static void test(int rw_loop, int truncate_loop, int append_loop,
- int create_loop)
-{
- static const int rw_flags[4] = { 0, O_RDONLY, O_WRONLY, O_RDWR };
- static const int create_flags[3] = { 0, O_CREAT /* nonexistent */ ,
- O_CREAT /* existent */
- };
- static const int truncate_flags[2] = { 0, O_TRUNC };
- static const int append_flags[2] = { 0, O_APPEND };
- int level;
- int flags;
- int i;
- int fd;
- static char buffer[1024];
- memset(buffer, 0, sizeof(buffer));
- snprintf(buffer, sizeof(buffer) - 1, "/tmp/file:a=%d:t=%d:c=%d:m=%d",
- append_loop, truncate_loop, create_loop, rw_loop);
- fprintf(exception_fp, "deny_rewrite %s\n", buffer);
- flags = rw_flags[rw_loop] | truncate_flags[truncate_loop] |
- append_flags[append_loop] | create_flags[create_loop];
- for (i = 1; i < 8; i++)
- fprintf(domain_fp, "delete %d %s\n", i, buffer);
- for (level = 0; level < 4; level++) {
- set_level(0);
- if (create_loop == 1)
- unlink(buffer);
- else
- close(open(buffer, O_CREAT, 0644));
- set_level(level);
- fd = open(buffer, flags, 0644);
- if (fd != EOF)
- close(fd);
- else
- fprintf(stderr, "%d: open(%04o) failed\n", level,
- flags);
- /*
- fd = open(buffer, flags, 0644)
- if (fd != EOF)
- close(fd);
- else
- fprintf(stderr, "%d: open(%04o) failed\n", level, flags);
- */
- /*
- fd = open(buffer, flags, 0644);
- if (fd != EOF)
- close(fd);
- else
- fprintf(stderr, "%d: open(%04o) failed\n", level, flags);
- */
- }
- for (i = 1; i < 8; i++)
- fprintf(domain_fp, "delete %d %s\n", i, buffer);
- fprintf(domain_fp, "delete allow_truncate %s\n", buffer);
- fprintf(domain_fp, "delete allow_create %s 0644\n", buffer);
- fprintf(domain_fp, "delete allow_rewrite %s\n", buffer);
- fd = open(buffer, flags, 0644);
- if (fd != EOF) {
- close(fd);
- fprintf(stderr, "%d: open(%04o) didn't fail\n", 3, flags);
- }
-}
-
-int main(void)
-{
- tomoyo_test_init();
- fprintf(profile_fp, "255-PREFERENCE::learning={ verbose=no }\n");
- fprintf(profile_fp, "255-PREFERENCE::enforcing={ verbose=no }\n");
- fprintf(profile_fp, "255-PREFERENCE::permissive={ verbose=no }\n");
- fprintf(profile_fp, "255-PREFERENCE::disabled={ verbose=no }\n");
- set_profile(0, "file");
- fprintf(profile_fp, "255-PREFERENCE::learning={ max_entry=2048 }\n");
- {
- int append_loop;
- for (append_loop = 0; append_loop < 2; append_loop++) {
- int truncate_loop;
- for (truncate_loop = 0; truncate_loop < 2;
- truncate_loop++) {
- int create_loop;
- for (create_loop = 0; create_loop < 3;
- create_loop++) {
- int rw_loop;
- for (rw_loop = 0; rw_loop < 4;
- rw_loop++)
- test(rw_loop, truncate_loop,
- append_loop, create_loop);
- }
- }
- }
- }
- fprintf(profile_fp, "255-CONFIG::file=disabled\n");
- printf("Done\n");
- clear_status();
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/tomoyo_file_test.c b/testcases/kernel/security/tomoyo/tomoyo_file_test.c
deleted file mode 100644
index 003f47720..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_file_test.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_file_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#include "include.h"
-
-static int should_fail = 0;
-
-static void show_prompt(const char *str)
-{
- printf("Testing %35s: (%s) ", str,
- should_fail ? "must fail" : "should success");
- errno = 0;
-}
-
-static void show_result(int result)
-{
- if (should_fail) {
- if (result == EOF) {
- if (errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- } else {
- printf("BUG!\n");
- }
- } else {
- if (result != EOF)
- printf("OK\n");
- else
- printf("%s\n", strerror(errno));
- }
-}
-
-static const char *dev_null_path = "/dev/null";
-static const char *truncate_path = "/tmp/truncate_test";
-static const char *ftruncate_path = "/tmp/ftruncate_test";
-static const char *open_creat_path = "/tmp/open_test";
-static const char *mknod_reg_path = "/tmp/mknod_reg_test";
-static const char *mknod_chr_path = "/tmp/mknod_chr_test";
-static const char *mknod_blk_path = "/tmp/mknod_blk_test";
-static const char *mknod_fifo_path = "/tmp/mknod_fifo_test";
-static const char *mknod_sock_path = "/tmp/mknod_sock_test";
-static const char *unlink_path = "/tmp/unlink_test";
-static const char *mkdir_path = "/tmp/mkdir_test";
-static const char *rmdir_path = "/tmp/rmdir_test";
-static const char *link_source_path = "/tmp/link_source_test";
-static const char *link_dest_path = "/tmp/link_dest_test";
-static const char *symlink_source_path = "/tmp/symlink_source_test";
-static const char *symlink_dest_path = "/tmp/symlink_dest_test";
-static const char *rename_source_path = "/tmp/rename_source_test";
-static const char *rename_dest_path = "/tmp/rename_dest_test";
-static const char *socket_path = "/tmp/socket_test";
-
-static int ftruncate_fd = EOF;
-
-static void stage_file_test(void)
-{
- int fd;
- {
- const char buffer[] = "32768 61000";
- show_prompt("sysctl(READ)");
- show_result(read_sysctl(TEST_SYSCTL_PATH, NULL, 0));
- show_prompt("sysctl(WRITE)");
- show_result(write_sysctl(TEST_SYSCTL_PATH, buffer));
- }
-
- /* QUESTION: Is there a file which can be passed to uselib()? */
- show_prompt("uselib()");
- show_result(uselib("/bin/true"));
-
- {
- int pipe_fd[2] = { EOF, EOF };
- int error = 0;
- fflush(stdout);
- fflush(stderr);
- if (pipe(pipe_fd) == -1)
- err(1, "pipe");
- if (fork() == 0) {
- execl("/bin/true", "/bin/true", NULL);
- if (write(pipe_fd[1], &errno, sizeof(errno)) == -1)
- err(1, "write");
- _exit(0);
- }
- close(pipe_fd[1]);
- (void)read(pipe_fd[0], &error, sizeof(error));
- show_prompt("execve()");
- errno = error;
- show_result(error ? EOF : 0);
- }
-
- show_prompt("open(O_RDONLY)");
- fd = open(dev_null_path, O_RDONLY);
- show_result(fd);
- if (fd != EOF)
- close(fd);
-
- show_prompt("open(O_WRONLY)");
- fd = open(dev_null_path, O_WRONLY);
- show_result(fd);
- if (fd != EOF)
- close(fd);
-
- show_prompt("open(O_RDWR)");
- fd = open(dev_null_path, O_RDWR);
- show_result(fd);
- if (fd != EOF)
- close(fd);
-
- show_prompt("open(O_CREAT | O_EXCL)");
- fd = open(open_creat_path, O_CREAT | O_EXCL, 0666);
- show_result(fd);
- if (fd != EOF)
- close(fd);
-
- show_prompt("open(O_TRUNC)");
- fd = open(truncate_path, O_TRUNC);
- show_result(fd);
- if (fd != EOF)
- close(fd);
-
- show_prompt("truncate()");
- show_result(truncate(truncate_path, 0));
-
- show_prompt("ftruncate()");
- show_result(ftruncate(ftruncate_fd, 0));
-
- show_prompt("mknod(S_IFREG)");
- show_result(mknod(mknod_reg_path, S_IFREG, 0));
-
- show_prompt("mknod(S_IFCHR)");
- show_result(mknod(mknod_chr_path, S_IFCHR, MKDEV(1, 3)));
-
- show_prompt("mknod(S_IFBLK)");
- show_result(mknod(mknod_blk_path, S_IFBLK, MKDEV(1, 0)));
-
- show_prompt("mknod(S_IFIFO)");
- show_result(mknod(mknod_fifo_path, S_IFIFO, 0));
-
- show_prompt("mknod(S_IFSOCK)");
- show_result(mknod(mknod_sock_path, S_IFSOCK, 0));
-
- show_prompt("mkdir()");
- show_result(mkdir(mkdir_path, 0600));
-
- show_prompt("rmdir()");
- show_result(rmdir(rmdir_path));
-
- show_prompt("unlink()");
- show_result(unlink(unlink_path));
-
- show_prompt("symlink()");
- show_result(symlink(symlink_dest_path, symlink_source_path));
-
- show_prompt("link()");
- show_result(link(link_source_path, link_dest_path));
-
- show_prompt("rename()");
- show_result(rename(rename_source_path, rename_dest_path));
-
- {
- struct sockaddr_un addr;
- int fd;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- show_prompt("unix_bind()");
- show_result(bind(fd, (struct sockaddr *)&addr, sizeof(addr)));
- if (fd != EOF)
- close(fd);
- }
-
- printf("\n\n");
-}
-
-static void create_files(void)
-{
- mkdir(rmdir_path, 0700);
- close(creat(link_source_path, 0600));
- close(creat(rename_source_path, 0600));
- close(creat(truncate_path, 0600));
- close(creat(unlink_path, 0600));
- ftruncate_fd = open(ftruncate_path, O_WRONLY | O_CREAT, 0600);
-}
-
-static void creanup_files(void)
-{
- if (ftruncate_fd != EOF)
- close(ftruncate_fd);
- ftruncate_fd = EOF;
- unlink(open_creat_path);
- unlink(mknod_reg_path);
- unlink(mknod_chr_path);
- unlink(mknod_blk_path);
- unlink(mknod_fifo_path);
- unlink(mknod_sock_path);
- rmdir(mkdir_path);
- unlink(symlink_source_path);
- unlink(symlink_dest_path);
- unlink(link_source_path);
- unlink(link_dest_path);
- unlink(rename_source_path);
- unlink(rename_dest_path);
- unlink(truncate_path);
- unlink(ftruncate_path);
- unlink(socket_path);
-}
-
-static void set_file_enforce(int enforce)
-{
- if (enforce) {
- set_profile(3, "file::execute");
- set_profile(3, "file::open");
- set_profile(3, "file::create");
- set_profile(3, "file::unlink");
- set_profile(3, "file::mkdir");
- set_profile(3, "file::rmdir");
- set_profile(3, "file::mkfifo");
- set_profile(3, "file::mksock");
- set_profile(3, "file::truncate");
- set_profile(3, "file::symlink");
- set_profile(3, "file::rewrite");
- set_profile(3, "file::mkblock");
- set_profile(3, "file::mkchar");
- set_profile(3, "file::link");
- set_profile(3, "file::rename");
- set_profile(3, "file::chmod");
- set_profile(3, "file::chown");
- set_profile(3, "file::chgrp");
- set_profile(3, "file::ioctl");
- set_profile(3, "file::chroot");
- set_profile(3, "file::mount");
- set_profile(3, "file::umount");
- set_profile(3, "file::pivot_root");
- } else {
- set_profile(0, "file::execute");
- set_profile(0, "file::open");
- set_profile(0, "file::create");
- set_profile(0, "file::unlink");
- set_profile(0, "file::mkdir");
- set_profile(0, "file::rmdir");
- set_profile(0, "file::mkfifo");
- set_profile(0, "file::mksock");
- set_profile(0, "file::truncate");
- set_profile(0, "file::symlink");
- set_profile(0, "file::rewrite");
- set_profile(0, "file::mkblock");
- set_profile(0, "file::mkchar");
- set_profile(0, "file::link");
- set_profile(0, "file::rename");
- set_profile(0, "file::chmod");
- set_profile(0, "file::chown");
- set_profile(0, "file::chgrp");
- set_profile(0, "file::ioctl");
- set_profile(0, "file::chroot");
- set_profile(0, "file::mount");
- set_profile(0, "file::umount");
- set_profile(0, "file::pivot_root");
- }
-}
-
-int main(void)
-{
- tomoyo_test_init();
-
- printf("***** Testing file hooks in enforce mode. *****\n");
- create_files();
- should_fail = 1;
- set_file_enforce(1);
- stage_file_test();
- set_file_enforce(0);
- clear_status();
- creanup_files();
-
- printf("***** Testing file hooks in permissive mode. *****\n");
- should_fail = 0;
- create_files();
- set_file_enforce(0);
- stage_file_test();
- creanup_files();
-
- clear_status();
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/tomoyo_filesystem_test.c b/testcases/kernel/security/tomoyo/tomoyo_filesystem_test.c
deleted file mode 100644
index e6e3bb087..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_filesystem_test.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_filesystem_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#define _GNU_SOURCE
-#include "include.h"
-
-static void show_prompt(const char *str, const int should_fail)
-{
- printf("Testing %60s: (%s) ", str,
- should_fail ? "must fail" : "should success");
- errno = 0;
-}
-
-#ifndef MS_MOVE
-#define MS_MOVE 8192
-#endif
-
-static const char *pivot_root_dir = "/sys/kernel/security/";
-
-static int child(void *arg)
-{
- errno = 0;
- pivot_root(pivot_root_dir, proc_policy_dir);
- return errno;
-}
-
-static void mount2(const char *source, const char *target,
- const char *filesystemtype)
-{
- if (mount(source, target, filesystemtype, 0, NULL)) {
- printf("BUG: mount() failed\n");
- fflush(stdout);
- }
-}
-
-static const unsigned char compressed_ext2_image_sample[1350] = {
- 0x1F, 0x8B, 0x08, 0x00, 0xA8, 0xF2, 0x96, 0x4B, 0x02, 0x03, 0xED, 0xDC,
- 0x3D, 0x4B, 0x5B, 0x51, 0x18, 0x07, 0xF0, 0xE7, 0xDE, 0xAB, 0x14, 0x8C,
- 0xAB, 0xD5, 0x9A, 0xF8, 0x36, 0x0B, 0xA1, 0xE0, 0xE0, 0xDC, 0xD0, 0xAD,
- 0xD0, 0xC5, 0xAF, 0x50, 0x9C, 0x42, 0x1D, 0x6A, 0xE6, 0xA6, 0x9B, 0x9B,
- 0x8B, 0xD8, 0xA5, 0x5B, 0x97, 0x2E, 0xF9, 0x0E, 0x85, 0x4C, 0xF6, 0x23,
- 0x74, 0x70, 0x55, 0x28, 0x52, 0xA8, 0xDD, 0xED, 0xB9, 0xB9, 0xB1, 0xA6,
- 0xEA, 0x24, 0xA5, 0x81, 0xDE, 0xDF, 0x0F, 0x9E, 0xDC, 0xB7, 0x13, 0x2E,
- 0xF7, 0xC0, 0xFF, 0x70, 0xCE, 0x85, 0x24, 0x02, 0xA8, 0xAB, 0x7E, 0xF9,
- 0x31, 0x13, 0xB1, 0x95, 0x36, 0xA7, 0x45, 0x44, 0x2F, 0x6D, 0xB3, 0xC9,
- 0x06, 0xEB, 0x55, 0xF5, 0xC7, 0x87, 0x9F, 0x7E, 0x1C, 0xBF, 0x88, 0x68,
- 0xC5, 0xCE, 0xF7, 0x6C, 0xD4, 0x6E, 0x74, 0xFC, 0xF2, 0x62, 0x74, 0xED,
- 0xFA, 0x7B, 0x8D, 0xB8, 0x69, 0x9F, 0x8F, 0xCF, 0x9F, 0x1D, 0x7E, 0x78,
- 0xF7, 0x6D, 0xD8, 0x79, 0xFF, 0x71, 0xD0, 0xED, 0xBC, 0xCD, 0x9A, 0xBD,
- 0x69, 0x3C, 0xEB, 0xE0, 0xCB, 0xF0, 0xA4, 0xF9, 0xF5, 0xF9, 0xCA, 0xE0,
- 0xE0, 0x72, 0xBB, 0x7B, 0xD4, 0x1A, 0xE6, 0x13, 0xD7, 0xAA, 0xE7, 0x82,
- 0x7A, 0x29, 0xAA, 0xF8, 0xC7, 0xEC, 0x28, 0xFF, 0xBD, 0xC8, 0x75, 0x09,
- 0xD4, 0xC6, 0x55, 0x92, 0x4D, 0x71, 0xFA, 0x71, 0x05, 0x4C, 0xCF, 0xA3,
- 0xBB, 0xE3, 0x01, 0x50, 0x0F, 0x93, 0xEB, 0xDF, 0xEB, 0xFA, 0x97, 0x13,
- 0x80, 0x8B, 0x67, 0xD5, 0x02, 0xE4, 0xEE, 0xFD, 0x8B, 0x3F, 0xD6, 0x22,
- 0x0B, 0xA6, 0x6A, 0xC0, 0x5F, 0xF6, 0xB9, 0x1C, 0x7F, 0x9E, 0xDE, 0x37,
- 0xFE, 0xE4, 0xB1, 0x34, 0xD1, 0xEE, 0x71, 0xAA, 0xC5, 0x54, 0xE5, 0xB9,
- 0x27, 0xA9, 0x96, 0x53, 0x35, 0xA3, 0x7C, 0x13, 0x1A, 0xB1, 0x92, 0x6A,
- 0x35, 0xD5, 0xDA, 0xF8, 0x75, 0xE9, 0x86, 0x6E, 0x05, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x81,
- 0xCA, 0xDF, 0xD8, 0xCF, 0x47, 0x96, 0xB7, 0x7F, 0xEF, 0xE7, 0x79, 0xBB,
- 0x5D, 0xFD, 0x87, 0xDF, 0x79, 0x31, 0x97, 0x77, 0xF7, 0xDE, 0xEC, 0x6F,
- 0xEE, 0xEE, 0xF5, 0x5E, 0xBF, 0xD2, 0x57, 0xF0, 0xBF, 0x69, 0xDC, 0xCA,
- 0xFF, 0xCF, 0xA2, 0xCA, 0x3F, 0x50, 0x13, 0x33, 0xBA, 0x00, 0xE4, 0x1F,
- 0x90, 0x7F, 0x40, 0xFE, 0x01, 0xF9, 0x07, 0xE4, 0x1F, 0x90, 0x7F, 0x40,
- 0xFE, 0x01, 0xF9, 0x07, 0xE4, 0x1F, 0x90, 0x7F, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFA, 0xF9, 0x05, 0x34, 0xF2,
- 0x14, 0x08, 0x00, 0x00, 0x10, 0x00
-};
-
-int main(void)
-{
- char c = 0;
- tomoyo_test_init();
-
- /* Test mount(). */
- {
- set_profile(3, "file::mount");
- show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 1);
- if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF &&
- errno == EPERM)
- printf("OK: Permission denied.\n");
- else if (errno == ENODEV)
- printf("OK: No such device.\n");
- else
- printf("BUG: %s\n", strerror(errno));
- set_profile(1, "file::mount");
- show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 0);
- if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF &&
- errno == ENOMEM)
- printf("OK: Out of memory.\n");
- else if (errno == ENODEV)
- printf("OK: No such device.\n");
- else
- printf("BUG: %s\n", strerror(errno));
- set_profile(3, "file::mount");
- show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 0);
- if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF &&
- errno == ENOMEM)
- printf("OK: Out of memory.\n");
- else if (errno == ENODEV)
- printf("OK: No such device.\n");
- else
- printf("BUG: %s\n", strerror(errno));
- fprintf(domain_fp, "delete allow_mount dev\\011name / "
- "fs\\011name 0\n");
- show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 1);
- if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF &&
- errno == EPERM)
- printf("OK: Permission denied.\n");
- else if (errno == ENODEV)
- printf("OK: No such device.\n");
- else
- printf("BUG: %s\n", strerror(errno));
- set_profile(1, "file::mount");
- show_prompt("mount(NULL, '/', 'tmpfs') ", 0);
- if (mount(NULL, "/", "tmpfs", 0, NULL))
- printf("BUG: %s\n", strerror(errno));
- else
- printf("OK: Success\n");
- set_profile(3, "file::mount");
- show_prompt("mount(NULL, '/', 'tmpfs') ", 0);
- if (mount(NULL, "/", "tmpfs", 0, NULL))
- printf("BUG: %s\n", strerror(errno));
- else
- printf("OK: Success\n");
- show_prompt("mount('anydev', '/', 'tmpfs') ", 0);
- if (mount("anydev", "/", "tmpfs", 0, NULL))
- printf("BUG: %s\n", strerror(errno));
- else
- printf("OK: Success\n");
- fprintf(domain_fp, "delete allow_mount <NULL> / tmpfs 0\n");
- fprintf(domain_fp, "allow_mount anydev / tmpfs 0\n");
- show_prompt("mount(NULL, '/', 'tmpfs') ", 0);
- if (mount(NULL, "/", "tmpfs", 0, NULL))
- printf("BUG: %s\n", strerror(errno));
- else
- printf("OK: Success\n");
- fprintf(domain_fp, "delete allow_mount anydev / tmpfs 0\n");
- set_profile(2, "file::mount");
- show_prompt("mount(NULL, NULL, 'tmpfs') ", 1);
- if (mount(NULL, NULL, "tmpfs", 0, NULL))
- printf("OK: %s\n", strerror(errno));
- else
- printf("BUG: Did not fail.\n");
- show_prompt("mount(NULL, NULL, NULL) ", 1);
- if (mount(NULL, NULL, NULL, 0, NULL))
- printf("OK: %s\n", strerror(errno));
- else
- printf("BUG: Did not fail.\n");
- show_prompt("mount('/', NULL, NULL) ", 1);
- if (mount("/", NULL, NULL, 0, NULL))
- printf("OK: %s\n", strerror(errno));
- else
- printf("BUG: Did not fail.\n");
- show_prompt("mount('/', NULL, 'tmpfs') ", 1);
- if (mount("/", NULL, "tmpfs", 0, NULL))
- printf("OK: %s\n", strerror(errno));
- else
- printf("BUG: Did not fail.\n");
- show_prompt("mount('/', '/', 'nonexistentfs') ", 1);
- if (mount("/", "/", "nonexistentfs", 0, NULL))
- printf("OK: %s\n", strerror(errno));
- else
- printf("BUG: Did not fail.\n");
- set_profile(0, "file::mount");
- }
-
- mkdir("/tmp/mount/", 0755);
- mkdir("/tmp/mount_bind/", 0755);
- mkdir("/tmp/mount_move/", 0755);
-
- /* Test mount(). */
- {
- static char buf[4096];
- char *dev_ram_path = realpath("/dev/ram0", NULL);
- if (!dev_ram_path)
- dev_ram_path = realpath("/dev/ram", NULL);
- if (!dev_ram_path) {
- dev_ram_path = "/dev/ram0";
- mknod(dev_ram_path, S_IFBLK, MKDEV(1, 0));
- }
- memset(buf, 0, sizeof(buf));
- {
- struct stat sbuf;
- FILE *fp = NULL;
- snprintf(buf, sizeof(buf) - 1, "zcat - > %s",
- dev_ram_path);
- if (lstat(dev_ram_path, &sbuf) == 0 &&
- S_ISBLK(sbuf.st_mode) && MAJOR(sbuf.st_rdev) == 1)
- fp = popen(buf, "w");
- if (fp) {
- if (fwrite(compressed_ext2_image_sample, 1,
- sizeof(compressed_ext2_image_sample),
- fp) !=
- sizeof(compressed_ext2_image_sample))
- err(1, "fwrite");
- pclose(fp);
- } else
- fprintf(stderr, "Can't write to %s .\n",
- dev_ram_path);
- }
- set_profile(3, "file::mount");
-
- /* Test standard case */
- show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for "
- "'/tmp/mount/'", 1);
- if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == EOF &&
- errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
-
- /* Test device_name with pattern */
- snprintf(buf, sizeof(buf) - 1, "mount('%s', '/tmp/mount/', "
- "'ext2') for '%s\\*'", dev_ram_path, dev_ram_path);
- show_prompt(buf, 1);
- if (mount(dev_ram_path, "/tmp/mount/", "ext2", MS_RDONLY, NULL)
- == EOF && errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
-
- /* Test dir_name with pattern */
- show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for "
- "'/tmp/\\?\\?\\?\\?\\?/'", 1);
- if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == EOF &&
- errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
-
- /* Test standard case */
- fprintf(domain_fp, "allow_mount none /tmp/mount/ tmpfs 0\n");
- show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for "
- "'/tmp/mount/'", 0);
- if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- fprintf(domain_fp,
- "delete allow_mount none /tmp/mount/ tmpfs 0\n");
-
- /* Test device_name with pattern */
- fprintf(domain_fp, "allow_mount %s\\* /tmp/mount/ ext2 1\n",
- dev_ram_path);
- snprintf(buf, sizeof(buf) - 1, "mount('%s', '/tmp/mount/', "
- "'ext2') for '%s\\*'", dev_ram_path, dev_ram_path);
- show_prompt(buf, 0);
- if (mount(dev_ram_path, "/tmp/mount/", "ext2", MS_RDONLY, NULL)
- == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- fprintf(domain_fp, "delete allow_mount %s\\* "
- "/tmp/mount/ ext2 1\n", dev_ram_path);
-
- /* Test dir_name with pattern */
- fprintf(domain_fp,
- "allow_mount none /tmp/\\?\\?\\?\\?\\?/ tmpfs 0\n");
- show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for "
- "'/tmp/\\?\\?\\?\\?\\?/'", 0);
- if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- fprintf(domain_fp, "delete allow_mount none "
- "/tmp/\\?\\?\\?\\?\\?/ tmpfs 0\n");
-
- set_profile(0, "file::mount");
- while (umount("/tmp/mount/") == 0)
- c++; /* Dummy. */
- }
-
- /* Test mount(). */
- {
- mount2("none", "/tmp/mount/", "tmpfs");
- set_profile(3, "file::mount");
-
- /* Test remount case */
- show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 1);
- if (mount("none", "/tmp/mount/", "tmpfs", MS_REMOUNT, NULL)
- == EOF && errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
- show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 1);
- if (mount(NULL, "/tmp/mount/", NULL, MS_REMOUNT, NULL) == EOF
- && errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
- fprintf(domain_fp, "allow_mount something /tmp/mount/ "
- "--remount 0\n");
- show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 0);
- if (mount(NULL, "/tmp/mount/", NULL, MS_REMOUNT, NULL))
- printf("BUG: %s\n", strerror(errno));
- else
- printf("OK: Success.\n");
- fprintf(domain_fp, "delete allow_mount something /tmp/mount/ "
- "--remount 0\n");
-
- /* Test bind case */
- show_prompt("mount('/tmp/mount/', '/tmp/mount_bind/', "
- "MS_BIND)", 1);
- if (mount("/tmp/mount/", "/tmp/mount_bind/", NULL, MS_BIND,
- NULL) == EOF && errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
-
- /* Test move case */
- show_prompt("mount('/tmp/mount/', '/tmp/mount_move/', "
- "MS_MOVE)", 1);
- if (mount("/tmp/mount/", "/tmp/mount_move/", NULL, MS_MOVE,
- NULL) == EOF && errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
-
- /* Test remount case */
- fprintf(domain_fp, "allow_mount any /tmp/mount/ --remount 0\n");
- show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 0);
- if (mount("none", "/tmp/mount/", "tmpfs", MS_REMOUNT, NULL)
- == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- fprintf(domain_fp, "delete allow_mount any /tmp/mount/ "
- "--remount 0\n");
-
- /* Test bind case */
- fprintf(domain_fp,
- "allow_mount /tmp/mount/ /tmp/mount_bind/ --bind 0\n");
- show_prompt("mount('/tmp/mount/', '/tmp/mount_bind', MS_BIND)",
- 0);
- if (mount("/tmp/mount/", "/tmp/mount_bind/", NULL, MS_BIND,
- NULL) == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- set_profile(0, "file::mount");
- umount("/tmp/mount_bind/");
- fprintf(domain_fp, "delete allow_mount /tmp/mount/ "
- "/tmp/mount_bind/ --bind 0\n");
-
- /* Test move case */
- set_profile(3, "file::mount");
- fprintf(domain_fp, "allow_unmount /tmp/mount/\n");
- fprintf(domain_fp, "allow_mount /tmp/mount/ /tmp/mount_move/ "
- "--move 0\n");
- show_prompt("mount('/tmp/mount/', '/tmp/mount_move/', "
- "MS_MOVE)", 0);
- if (mount("/tmp/mount/", "/tmp/mount_move/", NULL, MS_MOVE,
- NULL) == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- set_profile(0, "file::mount");
- umount("/tmp/mount_move/");
- fprintf(domain_fp, "delete allow_unmount /tmp/mount/\n");
- fprintf(domain_fp, "delete allow_mount /tmp/mount/ "
- "/tmp/mount_move/ --move 0\n");
-
- while (umount("/tmp/mount/") == 0)
- c++; /* Dummy. */
- }
-
- /* Test umount(). */
- {
- /* Test standard case */
- fprintf(domain_fp, "allow_unmount /tmp/mount/\n");
-
- set_profile(0, "file::umount");
- mount2("none", "/tmp/mount/", "tmpfs");
- set_profile(3, "file::umount");
- show_prompt("umount('/tmp/mount/') for '/tmp/mount/'", 0);
- if (umount("/tmp/mount/") == 0)
- printf("OK\n");
- else
- printf("BUG: %s\n", strerror(errno));
- fprintf(domain_fp, "delete allow_unmount /tmp/mount/\n");
-
- set_profile(0, "file::umount");
-
- mount2("none", "/tmp/mount/", "tmpfs");
- set_profile(3, "file::umount");
- show_prompt("umount('/tmp/mount/') for '/tmp/mount/'", 1);
- if (umount("/tmp/mount/") == EOF && errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("FAILED: %s\n", strerror(errno));
-
- /* Test pattern */
- fprintf(domain_fp, "allow_unmount /tmp/\\?\\?\\?\\?\\?/\n");
- set_profile(0, "file::umount");
- mount2("none", "/tmp/mount/", "tmpfs");
- set_profile(3, "file::umount");
- show_prompt("umount('/tmp/mount/') for "
- "'/tmp/\\?\\?\\?\\?\\?/'", 1);
- if (umount("/tmp/mount/") == 0)
- printf("OK\n");
- else
- printf("BUG: %s\n", strerror(errno));
- fprintf(domain_fp,
- "delete allow_unmount /tmp/\\?\\?\\?\\?\\?/\n");
-
- set_profile(0, "file::umount");
- while (umount("/tmp/mount/") == 0)
- c++; /* Dummy. */
- }
-
- /* Test chroot(). */
- {
- set_profile(3, "file::chroot");
-
- /* Test standard case */
- fprintf(domain_fp, "allow_chroot /tmp/mount/\n");
- show_prompt("chroot('/tmp/mount/') for '/tmp/mount/'", 0);
- fflush(stdout);
- if (fork() == 0) {
- if (chroot("/tmp/mount/") == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- fflush(stdout);
- _exit(0);
- }
- wait(NULL);
- fprintf(domain_fp, "delete allow_chroot /tmp/mount/\n");
-
- show_prompt("chroot('/tmp/mount/') for '/tmp/mount/'", 1);
- fflush(stdout);
- if (fork() == 0) {
- if (chroot("/tmp/mount/") == EOF && errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
- fflush(stdout);
- _exit(0);
- }
- wait(NULL);
-
- /* Test pattern */
- fprintf(domain_fp, "allow_chroot /tmp/\\?\\?\\?\\?\\?/\n");
- show_prompt("chroot('/tmp/mount/') for "
- "'/tmp/\\?\\?\\?\\?\\?/'", 0);
- fflush(stdout);
- if (fork() == 0) {
- if (chroot("/tmp/mount/") == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
- fflush(stdout);
- _exit(0);
- }
- wait(NULL);
- fprintf(domain_fp,
- "delete allow_chroot /tmp/\\?\\?\\?\\?\\?/\n");
-
- set_profile(0, "file::chroot");
- }
-
- /* Test pivot_root(). */
- {
- int error;
- static char stack[8192];
- set_profile(3, "file::pivot_root");
- fprintf(domain_fp, "allow_pivot_root %s %s\n",
- pivot_root_dir, proc_policy_dir);
- snprintf(stack, 8191, "pivot_root('%s', '%s')", pivot_root_dir,
- proc_policy_dir);
- show_prompt(stack, 0);
- {
- const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child,
- NULL);
- while (waitpid(pid, &error, __WALL) == EOF &&
- errno == EINTR)
- c++; /* Dummy. */
- }
- errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1;
- if (errno == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
-
- fprintf(domain_fp, "delete allow_pivot_root %s %s\n",
- pivot_root_dir, proc_policy_dir);
- snprintf(stack, 8191, "pivot_root('%s', '%s')", pivot_root_dir,
- proc_policy_dir);
- show_prompt(stack, 1);
- {
- const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child,
- NULL);
- while (waitpid(pid, &error, __WALL) == EOF &&
- errno == EINTR)
- c++; /* Dummy. */
- }
- errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1;
- if (errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG: %s\n", strerror(errno));
-
- set_profile(2, "file::pivot_root");
- snprintf(stack, 8191, "pivot_root('%s', '%s')", pivot_root_dir,
- proc_policy_dir);
- show_prompt(stack, 0);
- {
- const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child,
- NULL);
- while (waitpid(pid, &error, __WALL) == EOF &&
- errno == EINTR)
- c++; /* Dummy. */
- }
- errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1;
- if (errno == 0)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(errno));
-
- set_profile(0, "file::pivot_root");
-
- }
-
- rmdir("/tmp/mount_move/");
- rmdir("/tmp/mount_bind/");
- rmdir("/tmp/mount/");
-
- clear_status();
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/tomoyo_new_file_test.c b/testcases/kernel/security/tomoyo/tomoyo_new_file_test.c
deleted file mode 100644
index eb912d726..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_new_file_test.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_new_file_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#include "include.h"
-
-static const char *policy = "";
-
-static void show_result(int result, char should_success)
-{
- int error = errno;
- printf("%s : ", policy);
- if (should_success) {
- if (result != EOF)
- printf("OK\n");
- else
- printf("FAILED: %s\n", strerror(error));
- } else {
- if (result == EOF) {
- if (error == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("FAILED: %s\n", strerror(error));
- } else {
- printf("BUG: didn't fail.\n");
- }
- }
-}
-
-static void create2(const char *pathname)
-{
- set_profile(0, "file::create");
- set_profile(0, "file::open");
- close(creat(pathname, 0600));
- set_profile(3, "file::create");
- set_profile(3, "file::open");
- errno = 0;
-}
-
-static void mkdir2(const char *pathname)
-{
- set_profile(0, "file::mkdir");
- mkdir(pathname, 0600);
- set_profile(3, "file::mkdir");
- errno = 0;
-}
-
-static void unlink2(const char *pathname)
-{
- set_profile(0, "file::unlink");
- unlink(pathname);
- set_profile(3, "file::unlink");
- errno = 0;
-}
-
-static void rmdir2(const char *pathname)
-{
- set_profile(0, "file::rmdir");
- rmdir(pathname);
- set_profile(3, "file::rmdir");
- errno = 0;
-}
-
-static void mkfifo2(const char *pathname)
-{
- set_profile(0, "file::mkfifo");
- mkfifo(pathname, 0600);
- set_profile(3, "file::mkfifo");
- errno = 0;
-}
-
-static void stage_file_test(void)
-{
- const char buffer[] = "32768 61000";
- int pipe_fd[2] = { EOF, EOF };
- int error = 0;
- int fd;
- char pbuffer[1024];
- struct stat sbuf;
- struct sockaddr_un addr;
- struct ifreq ifreq;
- char *filename = "";
- set_profile(3, "file::execute");
- set_profile(3, "file::open");
- set_profile(3, "file::create");
- set_profile(3, "file::unlink");
- set_profile(3, "file::mkdir");
- set_profile(3, "file::rmdir");
- set_profile(3, "file::mkfifo");
- set_profile(3, "file::mksock");
- set_profile(3, "file::truncate");
- set_profile(3, "file::symlink");
- set_profile(3, "file::rewrite");
- set_profile(3, "file::mkblock");
- set_profile(3, "file::mkchar");
- set_profile(3, "file::link");
- set_profile(3, "file::rename");
- set_profile(3, "file::chmod");
- set_profile(3, "file::chown");
- set_profile(3, "file::chgrp");
- set_profile(3, "file::ioctl");
- set_profile(3, "file::chroot");
- set_profile(3, "file::mount");
- set_profile(3, "file::umount");
- set_profile(3, "file::pivot_root");
-
- policy = "allow_read /proc/sys/net/ipv4/ip_local_port_range";
- write_domain_policy(policy, 0);
- show_result(read_sysctl(TEST_SYSCTL_PATH, NULL, 0), 1);
- write_domain_policy(policy, 1);
- show_result(read_sysctl(TEST_SYSCTL_PATH, NULL, 0), 0);
-
- policy = "allow_write /proc/sys/net/ipv4/ip_local_port_range";
- write_domain_policy(policy, 0);
- show_result(write_sysctl(TEST_SYSCTL_PATH, buffer), 1);
- write_domain_policy(policy, 1);
- show_result(write_sysctl(TEST_SYSCTL_PATH, buffer), 0);
-
- policy = "allow_read/write /proc/sys/net/ipv4/ip_local_port_range";
- write_domain_policy(policy, 0);
- show_result(read_sysctl(TEST_SYSCTL_PATH, NULL, 0) &&
- write_sysctl(TEST_SYSCTL_PATH, buffer), 1);
- write_domain_policy(policy, 1);
- show_result(read_sysctl(TEST_SYSCTL_PATH, NULL, 0) &&
- write_sysctl(TEST_SYSCTL_PATH, buffer), 0);
-
- policy = "allow_read /bin/true";
- write_domain_policy(policy, 0);
- show_result(uselib("/bin/true"), 1);
- write_domain_policy(policy, 1);
- show_result(uselib("/bin/true"), 0);
-
- policy = "allow_execute /bin/true";
- write_domain_policy(policy, 0);
- fflush(stdout);
- fflush(stderr);
- if (pipe(pipe_fd) == -1)
- err(1, "pipe");
- if (fork() == 0) {
- execl("/bin/true", "/bin/true", NULL);
- if (write(pipe_fd[1], &errno, sizeof(errno)) == -1)
- err(1, "write");
- exit(0);
- }
- close(pipe_fd[1]);
- (void)read(pipe_fd[0], &error, sizeof(error));
- close(pipe_fd[0]);
- wait(NULL);
- errno = error;
- show_result(error ? EOF : 0, 1);
- write_domain_policy(policy, 1);
- fflush(stdout);
- fflush(stderr);
- if (pipe(pipe_fd) == -1)
- err(1, "pipe");
- if (fork() == 0) {
- execl("/bin/true", "/bin/true", NULL);
- if (write(pipe_fd[1], &errno, sizeof(errno)) == -1)
- err(1, "write");
- _exit(0);
- }
- close(pipe_fd[1]);
- (void)read(pipe_fd[0], &error, sizeof(error));
- close(pipe_fd[0]);
- wait(NULL);
- errno = error;
- show_result(errno ? EOF : 0, 0);
-
- policy = "allow_read /dev/null";
- write_domain_policy(policy, 0);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_read /dev/null";
- write_domain_policy(policy, 0);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_read /dev/null";
- write_domain_policy(policy, 0);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_read /dev/null";
- write_domain_policy(policy, 0);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- set_profile(3, "file::mkfifo");
- policy = "allow_mkfifo /tmp/mknod_fifo_test 0644";
- write_domain_policy(policy, 0);
- filename = "/tmp/mknod_fifo_test";
- show_result(mknod(filename, S_IFIFO | 0644, 0), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(mknod(filename, S_IFIFO | 0644, 0), 0);
-
- memset(pbuffer, 0, sizeof(pbuffer));
- memset(&sbuf, 0, sizeof(sbuf));
- filename = "/dev/null";
- stat(filename, &sbuf);
- snprintf(pbuffer, sizeof(pbuffer) - 1, "allow_write %s", filename);
- policy = pbuffer;
- write_domain_policy(policy, 0);
- fd = open(filename, O_WRONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open(filename, O_WRONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_read/write /tmp/fifo";
- mkfifo2("/tmp/fifo");
- write_domain_policy(policy, 0);
- fd = open("/tmp/fifo", O_RDWR);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/tmp/fifo", O_RDWR);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_read /dev/null";
- write_domain_policy(policy, 0);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/dev/null", O_RDONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_write /dev/null";
- write_domain_policy(policy, 0);
- fd = open("/dev/null", O_WRONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/dev/null", O_WRONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_read/write /dev/null";
- write_domain_policy(policy, 0);
- fd = open("/dev/null", O_RDWR);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open("/dev/null", O_RDWR);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- policy = "allow_create /tmp/open_test 0644";
- write_domain_policy(policy, 0);
- policy = "allow_write /tmp/open_test";
- write_domain_policy(policy, 0);
- fd = open("/tmp/open_test", O_WRONLY | O_CREAT | O_EXCL, 0644);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- unlink2("/tmp/open_test");
- write_domain_policy(policy, 1);
- fd = open("/tmp/open_test", O_WRONLY | O_CREAT | O_EXCL, 0644);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
- unlink2("/tmp/open_test");
-
- policy = "allow_create /tmp/open_test 0644";
- write_domain_policy(policy, 1);
-
- policy = "allow_write /tmp/open_test";
- write_domain_policy(policy, 0);
- policy = "allow_create /tmp/open_test 0644";
- write_domain_policy(policy, 0);
- fd = open("/tmp/open_test", O_WRONLY | O_CREAT | O_EXCL, 0644);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- unlink2("/tmp/open_test");
- write_domain_policy(policy, 1);
- fd = open("/tmp/open_test", O_WRONLY | O_CREAT | O_EXCL, 0644);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
- unlink2("/tmp/open_test");
- policy = "allow_write /tmp/open_test";
- write_domain_policy(policy, 1);
-
- filename = "/tmp/truncate_test";
- create2(filename);
-
- policy = "allow_truncate /tmp/truncate_test";
- write_domain_policy(policy, 0);
- policy = "allow_write /tmp/truncate_test";
- write_domain_policy(policy, 0);
- fd = open(filename, O_WRONLY | O_TRUNC);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open(filename, O_WRONLY | O_TRUNC);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
- policy = "allow_truncate /tmp/truncate_test";
- write_domain_policy(policy, 1);
-
- policy = "allow_write /tmp/truncate_test";
- write_domain_policy(policy, 0);
- policy = "allow_truncate /tmp/truncate_test";
- write_domain_policy(policy, 0);
- fd = open(filename, O_WRONLY | O_TRUNC);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- fd = open(filename, O_WRONLY | O_TRUNC);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
- policy = "allow_write /tmp/truncate_test";
- write_domain_policy(policy, 1);
-
- policy = "allow_truncate /tmp/truncate_test";
- write_domain_policy(policy, 0);
- show_result(truncate(filename, 0), 1);
- write_domain_policy(policy, 1);
- show_result(truncate(filename, 0), 0);
-
- policy = "allow_truncate /tmp/truncate_test";
- write_domain_policy(policy, 0);
- set_profile(0, "file::open");
- fd = open(filename, O_WRONLY);
- set_profile(3, "file::open");
- show_result(ftruncate(fd, 0), 1);
- write_domain_policy(policy, 1);
- show_result(ftruncate(fd, 0), 0);
- if (fd != EOF)
- close(fd);
-
- unlink2(filename);
-
- policy = "allow_create /tmp/mknod_reg_test 0644";
- write_domain_policy(policy, 0);
- filename = "/tmp/mknod_reg_test";
- show_result(mknod(filename, S_IFREG | 0644, 0), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(mknod(filename, S_IFREG | 0644, 0), 0);
-
- policy = "allow_mkchar /tmp/mknod_chr_test 0644 1 3";
- write_domain_policy(policy, 0);
- filename = "/tmp/mknod_chr_test";
- show_result(mknod(filename, S_IFCHR | 0644, MKDEV(1, 3)), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(mknod(filename, S_IFCHR | 0644, MKDEV(1, 3)), 0);
-
- policy = "allow_mkblock /tmp/mknod_blk_test 0644 1 0";
- write_domain_policy(policy, 0);
- filename = "/tmp/mknod_blk_test";
- show_result(mknod(filename, S_IFBLK | 0644, MKDEV(1, 0)), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(mknod(filename, S_IFBLK | 0644, MKDEV(1, 0)), 0);
-
- policy = "allow_mkfifo /tmp/mknod_fifo_test 0644";
- write_domain_policy(policy, 0);
- filename = "/tmp/mknod_fifo_test";
- show_result(mknod(filename, S_IFIFO | 0644, 0), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(mknod(filename, S_IFIFO | 0644, 0), 0);
-
- policy = "allow_mksock /tmp/mknod_sock_test 0644";
- write_domain_policy(policy, 0);
- filename = "/tmp/mknod_sock_test";
- show_result(mknod(filename, S_IFSOCK | 0644, 0), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(mknod(filename, S_IFSOCK | 0644, 0), 0);
-
- policy = "allow_mkdir /tmp/mkdir_test/ 0600";
- write_domain_policy(policy, 0);
- filename = "/tmp/mkdir_test";
- show_result(mkdir(filename, 0600), 1);
- write_domain_policy(policy, 1);
- rmdir2(filename);
- show_result(mkdir(filename, 0600), 0);
-
- policy = "allow_rmdir /tmp/rmdir_test/";
- write_domain_policy(policy, 0);
- filename = "/tmp/rmdir_test";
- mkdir2(filename);
- show_result(rmdir(filename), 1);
- write_domain_policy(policy, 1);
- mkdir2(filename);
- show_result(rmdir(filename), 0);
- rmdir2(filename);
-
- policy = "allow_unlink /tmp/unlink_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/unlink_test";
- create2(filename);
- show_result(unlink(filename), 1);
- write_domain_policy(policy, 1);
- create2(filename);
- show_result(unlink(filename), 0);
- unlink2(filename);
-
- policy = "allow_symlink /tmp/symlink_source_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/symlink_source_test";
- show_result(symlink("/tmp/symlink_dest_test", filename), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(symlink("/tmp/symlink_dest_test", filename), 0);
-
- policy = "allow_symlink /tmp/symlink_source_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/symlink_source_test";
- show_result(symlink("/tmp/symlink_dest_test", filename), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(symlink("/tmp/symlink_dest_test", filename), 0);
-
- policy = "allow_symlink /tmp/symlink_source_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/symlink_source_test";
- show_result(symlink("/tmp/symlink_dest_test", filename), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(symlink("/tmp/symlink_dest_test", filename), 0);
-
- policy = "allow_symlink /tmp/symlink_source_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/symlink_source_test";
- show_result(symlink("/tmp/symlink_dest_test", filename), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(symlink("/tmp/symlink_dest_test", filename), 0);
-
- policy = "allow_symlink /tmp/symlink_source_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/symlink_source_test";
- show_result(symlink("/tmp/symlink_dest_test", filename), 1);
- write_domain_policy(policy, 1);
- unlink2(filename);
- show_result(symlink("/tmp/symlink_dest_test", filename), 0);
-
- policy = "allow_link /tmp/link_source_test /tmp/link_dest_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/link_source_test";
- create2(filename);
- show_result(link(filename, "/tmp/link_dest_test"), 1);
- write_domain_policy(policy, 1);
- unlink2("/tmp/link_dest_test");
- show_result(link(filename, "/tmp/link_dest_test"), 0);
- unlink2(filename);
-
- policy = "allow_rename /tmp/rename_source_test /tmp/rename_dest_test";
- write_domain_policy(policy, 0);
- filename = "/tmp/rename_source_test";
- create2(filename);
- show_result(rename(filename, "/tmp/rename_dest_test"), 1);
- write_domain_policy(policy, 1);
- unlink2("/tmp/rename_dest_test");
- create2(filename);
- show_result(rename(filename, "/tmp/rename_dest_test"), 0);
- unlink2(filename);
-
- policy = "allow_mksock /tmp/socket_test 0755";
- write_domain_policy(policy, 0);
- filename = "/tmp/socket_test";
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, filename, sizeof(addr.sun_path) - 1);
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- show_result(bind(fd, (struct sockaddr *)&addr, sizeof(addr)), 1);
- if (fd != EOF)
- close(fd);
- write_domain_policy(policy, 1);
- unlink2(filename);
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- show_result(bind(fd, (struct sockaddr *)&addr, sizeof(addr)), 0);
- if (fd != EOF)
- close(fd);
-
- filename = "/tmp/rewrite_test";
- create2(filename);
- policy = "allow_read/write /tmp/rewrite_test";
- write_domain_policy(policy, 0);
- write_exception_policy("deny_rewrite /tmp/rewrite_test", 0);
- policy = "allow_truncate /tmp/rewrite_test";
- write_domain_policy(policy, 0);
-
- fd = open(filename, O_RDONLY);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
-
- fd = open(filename, O_WRONLY | O_APPEND);
- show_result(fd, 1);
- if (fd != EOF)
- close(fd);
-
- fd = open(filename, O_WRONLY);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- fd = open(filename, O_WRONLY | O_TRUNC);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- fd = open(filename, O_WRONLY | O_TRUNC | O_APPEND);
- show_result(fd, 0);
- if (fd != EOF)
- close(fd);
-
- show_result(truncate(filename, 0), 0);
-
- set_profile(0, "file::open");
- fd = open(filename, O_WRONLY | O_APPEND);
- set_profile(3, "file::open");
- show_result(ftruncate(fd, 0), 0);
-
- show_result(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_APPEND), 0);
- if (fd != EOF)
- close(fd);
-
- write_domain_policy(policy, 1);
-
- policy = "allow_read/write /tmp/rewrite_test";
- write_domain_policy(policy, 1);
- write_exception_policy("deny_rewrite /tmp/rewrite_test", 1);
-
- unlink2(filename);
-
- policy = "allow_ioctl socket:[family=2:type=2:protocol=17] "
- "35122-35124";
- write_domain_policy(policy, 0);
- fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
- memset(&ifreq, 0, sizeof(ifreq));
- snprintf(ifreq.ifr_name, sizeof(ifreq.ifr_name) - 1, "lo");
- show_result(ioctl(fd, 35123, &ifreq), 1);
- write_domain_policy(policy, 1);
- policy = "allow_ioctl " "socket:[family=2:type=2:protocol=17] 0-35122";
- write_domain_policy(policy, 0);
- show_result(ioctl(fd, 35123, &ifreq), 0);
- write_domain_policy(policy, 1);
- if (fd != EOF)
- close(fd);
-}
-
-int main(void)
-{
- tomoyo_test_init();
- fprintf(domain_fp, "%s /bin/true\n", self_domain);
- fprintf(domain_fp, "use_profile 255\n");
- fprintf(domain_fp, "select pid=%u\n", pid);
- fprintf(profile_fp, "255-PREFERENCE::audit={ max_reject_log=1024 }\n");
- stage_file_test();
- fprintf(domain_fp, "use_profile 0\n");
- clear_status();
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/tomoyo_new_test.c b/testcases/kernel/security/tomoyo/tomoyo_new_test.c
deleted file mode 100644
index a1ab259e5..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_new_test.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_new_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#include "include.h"
-
-static int result;
-static int error;
-
-static void show_result(const char *test, int should_success)
-{
- error = errno;
- printf("%s : ", test);
- if (should_success) {
- if (error == 0)
- printf("OK (%d)\n", result);
- else
- printf("FAILED: %s\n", strerror(error));
- } else {
- if (error == 0)
- printf("BUG: Didn't fail (%d)\n", result);
- else if (error == EPERM)
- printf("OK: permission denied\n");
- else
- printf("FAILED: %s\n", strerror(error));
- }
-}
-
-static void test_read_etc_fstab(void)
-{
- result = open("/etc/fstab", O_RDONLY);
-}
-
-static void test_write_dev_null(void)
-{
- result = open("/dev/null", O_WRONLY);
-}
-
-static void cleanup_file_open(void)
-{
- if (result != EOF)
- close(result);
-}
-
-static void test_mkdir_testdir(void)
-{
- result = mkdir("/tmp/testdir", 0755);
-}
-
-static void cleanup_mkdir_testdir(void)
-{
- rmdir("/tmp/testdir");
-}
-
-static void setup_mkdir_testdir(void)
-{
- mkdir("/tmp/testdir", 0755);
-}
-
-static void test_rmdir_testdir(void)
-{
- result = rmdir("/tmp/testdir");
-}
-
-static void setup_execute_bin_true(void)
-{
- fprintf(domain_fp, "%s /bin/true\n", self_domain);
- fprintf(domain_fp, "use_profile 0\n");
- fprintf(domain_fp, "select pid=%u\n", pid);
-}
-
-static void cleanup_execute_bin_true(void)
-{
- wait(NULL);
- fprintf(domain_fp, "delete %s /bin/true\n", self_domain);
- fprintf(domain_fp, "select pid=%u\n", pid);
-}
-
-static void test_execute_bin_true(void)
-{
- char *argv[] = { "/bin/true", NULL };
- char *envp[] = { "HOME=/", NULL };
- int pipe_fd[2] = { EOF, EOF };
- if (pipe(pipe_fd) == -1)
- err(1, "pipe");
- switch (fork()) {
- case 0:
- execve("/bin/true", argv, envp);
- error = errno;
- if (write(pipe_fd[1], &error, sizeof(error)) == -1)
- err(1, "write");
- _exit(0);
- break;
- case -1:
- error = ENOMEM;
- break;
- }
- close(pipe_fd[1]);
- (void)read(pipe_fd[0], &error, sizeof(error));
- close(pipe_fd[0]);
- result = error ? EOF : 0;
- errno = error;
-}
-
-static void test_chmod_dev_null(void)
-{
- result = chmod("/dev/null", 0666);
-}
-
-static void test_chown_dev_null(void)
-{
- result = chown("/dev/null", 0, -1);
-}
-
-static void test_chgrp_dev_null(void)
-{
- result = chown("/dev/null", -1, 0);
-}
-
-static void test_ioctl_dev_null(void)
-{
- int fd = open("/dev/null", O_RDWR);
- errno = 0;
- result = ioctl(fd, 0x5451, NULL);
- error = errno;
- close(fd);
- errno = error;
-}
-
-static void setup_chmod_group(void)
-{
- write_exception_policy("path_group CHMOD_TARGET /dev/null", 0);
- write_exception_policy("number_group CHMOD_MODES 0666", 0);
-}
-
-static void cleanup_chmod_group(void)
-{
- write_exception_policy("path_group CHMOD_TARGET /dev/null", 1);
- write_exception_policy("number_group CHMOD_MODES 0666", 1);
-}
-
-static void setup_chown_group(void)
-{
- write_exception_policy("path_group CHOWN_TARGET /dev/\\*", 0);
- write_exception_policy("number_group CHOWN_IDS 0x0-0xFFFE", 0);
-}
-
-static void cleanup_chown_group(void)
-{
- write_exception_policy("path_group CHOWN_TARGET /dev/\\*", 1);
- write_exception_policy("number_group CHOWN_IDS 0x0-0xFFFE", 1);
-}
-
-static void setup_ioctl_group(void)
-{
- write_exception_policy("path_group IOCTL_TARGET /dev/\\*", 0);
- write_exception_policy("number_group IOCTL_NUMBERS 0x5450-0x5452", 0);
-}
-
-static void cleanup_ioctl_group(void)
-{
- write_exception_policy("path_group IOCTL_TARGET /dev/\\*", 1);
- write_exception_policy("number_group IOCTL_NUMBERS 0x5450-0x5452", 1);
-}
-
-static void setup_open_group(void)
-{
- write_exception_policy("path_group READABLE /etc/\\*", 0);
- write_exception_policy("number_group READABLE_IDS 0-0xFFF", 0);
-}
-
-static void cleanup_open_group(void)
-{
- cleanup_file_open();
- write_exception_policy("path_group READABLE /etc/\\*", 1);
- write_exception_policy("number_group READABLE_IDS 0-0xFFF", 1);
-}
-
-static void test_file_open_0(void)
-{
- result = open("/tmp/testfile0", O_RDONLY, 0600);
-}
-
-static void test_file_open_1(void)
-{
- result = open("/tmp/testfile1", O_CREAT | O_RDONLY, 0600);
-}
-
-static void test_file_open_2(void)
-{
- result = open("/tmp/testfile2", O_TRUNC | O_RDONLY, 0600);
-}
-
-static void test_file_open_3(void)
-{
- result = open("/tmp/testfile3", O_TRUNC | O_CREAT | O_RDONLY, 0600);
-}
-
-static void test_file_open_4(void)
-{
- result = open("/tmp/testfile4", O_APPEND | O_RDONLY, 0600);
-}
-
-static void test_file_open_5(void)
-{
- result = open("/tmp/testfile5", O_APPEND | O_CREAT | O_RDONLY, 0600);
-}
-
-static void test_file_open_6(void)
-{
- result = open("/tmp/testfile6", O_APPEND | O_TRUNC | O_RDONLY, 0600);
-}
-
-static void test_file_open_7(void)
-{
- result = open("/tmp/testfile7",
- O_APPEND | O_TRUNC | O_CREAT | O_RDONLY, 0600);
-}
-
-static void test_file_open_8(void)
-{
- result = open("/tmp/testfile8", O_WRONLY, 0600);
-}
-
-static void test_file_open_9(void)
-{
- result = open("/tmp/testfile9", O_CREAT | O_WRONLY, 0600);
-}
-
-static void test_file_open_10(void)
-{
- result = open("/tmp/testfile10", O_TRUNC | O_WRONLY, 0600);
-}
-
-static void test_file_open_11(void)
-{
- result = open("/tmp/testfile11", O_TRUNC | O_CREAT | O_WRONLY, 0600);
-}
-
-static void test_file_open_12(void)
-{
- result = open("/tmp/testfile12", O_APPEND | O_WRONLY, 0600);
-}
-
-static void test_file_open_13(void)
-{
- result = open("/tmp/testfile13", O_APPEND | O_CREAT | O_WRONLY, 0600);
-}
-
-static void test_file_open_14(void)
-{
- result = open("/tmp/testfile14", O_APPEND | O_TRUNC | O_WRONLY, 0600);
-}
-
-static void test_file_open_15(void)
-{
- result = open("/tmp/testfile15",
- O_APPEND | O_TRUNC | O_CREAT | O_WRONLY, 0600);
-}
-
-static void test_file_open_16(void)
-{
- result = open("/tmp/testfile16", O_RDWR, 0600);
-}
-
-static void test_file_open_17(void)
-{
- result = open("/tmp/testfile17", O_CREAT | O_RDWR, 0600);
-}
-
-static void test_file_open_18(void)
-{
- result = open("/tmp/testfile18", O_TRUNC | O_RDWR, 0600);
-}
-
-static void test_file_open_19(void)
-{
- result = open("/tmp/testfile19", O_TRUNC | O_CREAT | O_RDWR, 0600);
-}
-
-static void test_file_open_20(void)
-{
- result = open("/tmp/testfile20", O_APPEND | O_RDWR, 0600);
-}
-
-static void test_file_open_21(void)
-{
- result = open("/tmp/testfile21", O_APPEND | O_CREAT | O_RDWR, 0600);
-}
-
-static void test_file_open_22(void)
-{
- result = open("/tmp/testfile22", O_APPEND | O_TRUNC | O_RDWR, 0600);
-}
-
-static void test_file_open_23(void)
-{
- result = open("/tmp/testfile23", O_APPEND | O_TRUNC | O_CREAT | O_RDWR,
- 0600);
-}
-
-static void setup_test_file(void)
-{
- int i;
- char buffer[32];
- buffer[31] = '\0';
- for (i = 0; i < 24; i += 2) {
- snprintf(buffer, sizeof(buffer) - 1, "/tmp/testfile%u", i);
- close(open(buffer, O_WRONLY | O_CREAT, 0600));
- }
- write_exception_policy("deny_rewrite /tmp/testfile\\$", 0);
-}
-
-static void setup_test_file_truncate(void)
-{
- setup_test_file();
- write_domain_policy("allow_truncate /tmp/testfile\\$", 0);
- set_profile(3, "file::truncate");
-}
-
-static void setup_all_test_file(void)
-{
- int i;
- char buffer[32];
- buffer[31] = '\0';
- for (i = 0; i < 24; i++) {
- snprintf(buffer, sizeof(buffer) - 1, "/tmp/testfile%u", i);
- close(open(buffer, O_WRONLY | O_CREAT, 0600));
- }
- write_exception_policy("deny_rewrite /tmp/testfile\\$", 0);
-}
-
-static void setup_all_test_file_truncate(void)
-{
- setup_all_test_file();
- write_domain_policy("allow_truncate /tmp/testfile\\$", 0);
- set_profile(3, "file::truncate");
-}
-
-static void cleanup_test_file(void)
-{
- int i;
- char buffer[32];
- buffer[31] = '\0';
- for (i = 0; i < 24; i++) {
- snprintf(buffer, sizeof(buffer) - 1, "/tmp/testfile%u", i);
- unlink(buffer);
- }
- write_exception_policy("deny_rewrite /tmp/testfile\\$", 1);
- cleanup_file_open();
-}
-
-static void cleanup_test_file_truncate(void)
-{
- cleanup_test_file();
- write_domain_policy("allow_truncate /tmp/testfile\\$", 1);
- set_profile(0, "file::truncate");
-}
-
-static struct test_struct {
- void (*do_setup) (void);
- void (*do_test) (void);
- void (*do_cleanup) (void);
- const char *name;
- const char *policy;
-} tests[] = {
- {
- NULL, test_read_etc_fstab, cleanup_file_open, "file::open",
- "allow_read /etc/fstab"}, {
- NULL, test_read_etc_fstab, cleanup_file_open, "file::open",
- "allow_read /etc/fstab"}, {
- NULL, test_read_etc_fstab, cleanup_file_open, "file::open",
- "allow_read /etc/fstab"}, {
- setup_open_group, test_read_etc_fstab, cleanup_open_group,
- "file::open", "allow_read @READABLE"}, {
- NULL, test_write_dev_null, cleanup_file_open, "file::open",
- "allow_write /dev/null"}, {
- NULL, test_write_dev_null, cleanup_file_open, "file::open",
- "allow_write /dev/null"}, {
- NULL, test_write_dev_null, cleanup_file_open, "file::open",
- "allow_write /dev/null"}, {
- cleanup_mkdir_testdir, test_mkdir_testdir,
- cleanup_mkdir_testdir, "file::mkdir",
- "allow_mkdir /tmp/testdir/ 0755"}, {
- cleanup_mkdir_testdir, test_mkdir_testdir,
- cleanup_mkdir_testdir, "file::mkdir",
- "allow_mkdir /tmp/testdir/ 0755"}, {
- cleanup_mkdir_testdir, test_mkdir_testdir,
- cleanup_mkdir_testdir, "file::mkdir",
- "allow_mkdir /tmp/testdir/ 0755"}, {
- setup_mkdir_testdir, test_rmdir_testdir, cleanup_mkdir_testdir,
- "file::rmdir", "allow_rmdir /tmp/testdir/"}, {
- setup_mkdir_testdir, test_rmdir_testdir, cleanup_mkdir_testdir,
- "file::rmdir", "allow_rmdir /tmp/testdir/"}, {
- setup_mkdir_testdir, test_rmdir_testdir, cleanup_mkdir_testdir,
- "file::rmdir", "allow_rmdir /tmp/testdir/"}, {
- setup_execute_bin_true, test_execute_bin_true,
- cleanup_execute_bin_true, "file::execute",
- "allow_execute /bin/true"}, {
- setup_execute_bin_true, test_execute_bin_true,
- cleanup_execute_bin_true, "file::execute",
- "allow_execute /bin/true"}, {
- setup_execute_bin_true, test_execute_bin_true,
- cleanup_execute_bin_true, "file::execute",
- "allow_execute /bin/true"}, {
- NULL, test_chmod_dev_null, NULL, "file::chmod",
- "allow_chmod /dev/null 0666"}, {
- NULL, test_chown_dev_null, NULL, "file::chown",
- "allow_chown /dev/null 0"}, {
- NULL, test_chgrp_dev_null, NULL, "file::chgrp",
- "allow_chgrp /dev/null 0"}, {
- NULL, test_ioctl_dev_null, NULL, "file::ioctl",
- "allow_ioctl /dev/null 0x5451"}, {
- setup_chmod_group, test_chmod_dev_null, cleanup_chmod_group,
- "file::chmod", "allow_chmod @CHMOD_TARGET @CHMOD_MODES"}, {
- setup_chown_group, test_chown_dev_null, cleanup_chown_group,
- "file::chown", "allow_chown @CHOWN_TARGET @CHOWN_IDS"}, {
- setup_chown_group, test_chgrp_dev_null, cleanup_chown_group,
- "file::chgrp", "allow_chgrp @CHOWN_TARGET @CHOWN_IDS"}, {
- setup_ioctl_group, test_ioctl_dev_null, cleanup_ioctl_group,
- "file::ioctl", "allow_ioctl @IOCTL_TARGET @IOCTL_NUMBERS"},
- {
- setup_test_file, test_file_open_0, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile0"}, {
- setup_test_file, test_file_open_1, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile1"}, {
- setup_test_file, test_file_open_1, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile1 0600"}, {
- setup_test_file, test_file_open_2, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile2"}, {
- setup_test_file, test_file_open_2, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile2"}, {
- setup_test_file_truncate, test_file_open_2,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile2"}, {
- setup_test_file, test_file_open_3, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile3"}, {
- setup_test_file, test_file_open_3, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile3 0600"}, {
- setup_test_file, test_file_open_4, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile4"}, {
- setup_test_file, test_file_open_5, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile5"}, {
- setup_test_file, test_file_open_5, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile5 0600"}, {
- setup_test_file, test_file_open_6, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile6"}, {
- setup_test_file, test_file_open_6, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile6"}, {
- setup_test_file_truncate, test_file_open_6,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile6"}, {
- setup_test_file, test_file_open_7, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile7"}, {
- setup_test_file, test_file_open_7, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile7 0600"}, {
- setup_test_file, test_file_open_8, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile8"}, {
- setup_test_file, test_file_open_8, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile8"}, {
- setup_test_file, test_file_open_9, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile9"}, {
- setup_test_file, test_file_open_9, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile9 0600"}, {
- setup_test_file, test_file_open_9, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile9"}, {
- setup_test_file, test_file_open_10, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile10"}, {
- setup_test_file, test_file_open_10, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile10"}, {
- setup_test_file, test_file_open_10, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile10"}, {
- setup_test_file, test_file_open_11, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile11"}, {
- setup_test_file, test_file_open_11, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile11 0600"}, {
- setup_test_file, test_file_open_11, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile11"}, {
- setup_test_file, test_file_open_12, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile12"}, {
- setup_test_file, test_file_open_13, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile13"}, {
- setup_test_file, test_file_open_13, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile13 0600"}, {
- setup_test_file, test_file_open_14, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile14"}, {
- setup_test_file, test_file_open_14, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile14"}, {
- setup_test_file_truncate, test_file_open_14,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile14"}, {
- setup_test_file, test_file_open_15, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile15"}, {
- setup_test_file, test_file_open_15, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile15 0600"}, {
- setup_test_file, test_file_open_16, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile16"}, {
- setup_test_file, test_file_open_16, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile16"}, {
- setup_test_file, test_file_open_17, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile17"}, {
- setup_test_file, test_file_open_17, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile17 0600"}, {
- setup_test_file, test_file_open_17, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile17"}, {
- setup_test_file, test_file_open_18, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile18"}, {
- setup_test_file, test_file_open_18, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile18"}, {
- setup_test_file, test_file_open_18, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile18"}, {
- setup_test_file, test_file_open_19, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile19"}, {
- setup_test_file, test_file_open_19, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile19 0600"}, {
- setup_test_file, test_file_open_19, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile19"}, {
- setup_test_file, test_file_open_20, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile20"}, {
- setup_test_file, test_file_open_21, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile21"}, {
- setup_test_file, test_file_open_21, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile21 0600"}, {
- setup_test_file, test_file_open_22, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile22"}, {
- setup_test_file, test_file_open_22, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile22"}, {
- setup_test_file_truncate, test_file_open_22,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile22"}, {
- setup_test_file, test_file_open_23, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile23"}, {
- setup_test_file, test_file_open_23, cleanup_test_file,
- "file::create", "allow_create /tmp/testfile23 0600"}, {
- setup_all_test_file, test_file_open_0, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile0"}, {
- setup_all_test_file, test_file_open_2, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile2"}, {
- setup_all_test_file, test_file_open_2, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile2"}, {
- setup_all_test_file_truncate, test_file_open_2,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile2"}, {
- setup_all_test_file, test_file_open_4, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile4"}, {
- setup_all_test_file, test_file_open_6, cleanup_test_file,
- "file::open", "allow_read /tmp/testfile6"}, {
- setup_all_test_file, test_file_open_6, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile6"}, {
- setup_all_test_file_truncate, test_file_open_6,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile6"}, {
- setup_all_test_file, test_file_open_8, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile8"}, {
- setup_all_test_file, test_file_open_8, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile8"}, {
- setup_all_test_file, test_file_open_10, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile10"}, {
- setup_all_test_file, test_file_open_10, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile10"}, {
- setup_all_test_file, test_file_open_10, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile10"}, {
- setup_all_test_file, test_file_open_12, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile12"}, {
- setup_all_test_file, test_file_open_14, cleanup_test_file,
- "file::open", "allow_write /tmp/testfile14"}, {
- setup_all_test_file, test_file_open_14, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile14"}, {
- setup_all_test_file_truncate, test_file_open_14,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile14"}, {
- setup_all_test_file, test_file_open_16, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile16"}, {
- setup_all_test_file, test_file_open_16, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile16"}, {
- setup_all_test_file, test_file_open_18, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile18"}, {
- setup_all_test_file, test_file_open_18, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile18"}, {
- setup_all_test_file, test_file_open_18, cleanup_test_file,
- "file::rewrite", "allow_rewrite /tmp/testfile18"}, {
- setup_all_test_file, test_file_open_20, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile20"}, {
- setup_all_test_file, test_file_open_22, cleanup_test_file,
- "file::open", "allow_read/write /tmp/testfile22"}, {
- setup_all_test_file, test_file_open_22, cleanup_test_file,
- "file::truncate", "allow_truncate /tmp/testfile22"}, {
- setup_all_test_file_truncate, test_file_open_22,
- cleanup_test_file_truncate, "file::rewrite",
- "allow_rewrite /tmp/testfile22"}, {
- NULL}
-};
-
-int main(void)
-{
- int i;
- tomoyo_test_init();
- for (i = 0; tests[i].do_test; i++) {
- int trial;
- for (trial = 0; trial < 2; trial++) {
- int should_fail;
- for (should_fail = 0; should_fail < 2; should_fail++) {
- if (tests[i].do_setup)
- tests[i].do_setup();
- if (!should_fail)
- write_domain_policy(tests[i].policy, 0);
- set_profile(3, tests[i].name);
- tests[i].do_test();
- show_result(tests[i].policy, !should_fail);
- set_profile(0, tests[i].name);
- if (tests[i].do_cleanup)
- tests[i].do_cleanup();
- if (!should_fail)
- write_domain_policy(tests[i].policy, 1);
- }
- }
- }
- for (i = 0; tests[i].do_test; i++) {
- int mode;
- for (mode = 0; mode < 4; mode++) {
- if (tests[i].do_setup)
- tests[i].do_setup();
- set_profile(mode, tests[i].name);
- tests[i].do_test();
- show_result(tests[i].name, 1);
- set_profile(0, tests[i].name);
- if (tests[i].do_cleanup)
- tests[i].do_cleanup();
- }
- }
- fprintf(domain_fp, "delete %s\n", self_domain);
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/tomoyo_policy_io_test.c b/testcases/kernel/security/tomoyo/tomoyo_policy_io_test.c
deleted file mode 100644
index b1897a0fc..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_policy_io_test.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_policy_io_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#include "include.h"
-
-static FILE *policy_fp = NULL;
-static const char *policy_file = "";
-
-static void try_io(const char *policy, const char should_success)
-{
- FILE *fp = fopen(policy_file, "r");
- char buffer[8192];
- int policy_found = 0;
- memset(buffer, 0, sizeof(buffer));
- printf("%s: ", policy);
- fprintf(policy_fp, "%s\n", policy);
- if (!fp) {
- printf("BUG: policy read failed\n");
- return;
- }
- while (fgets(buffer, sizeof(buffer) - 1, fp)) {
- char *cp = strchr(buffer, '\n');
- if (cp)
- *cp = '\0';
- if (!strcmp(buffer, policy)) {
- policy_found = 1;
- break;
- }
- }
- fclose(fp);
- if (should_success) {
- if (policy_found)
- printf("OK\n");
- else
- printf("BUG: policy write failed\n");
- } else {
- if (!policy_found)
- printf("OK : write rejected.\n");
- else
- printf("BUG: policy write not rejected.\n");
- }
- fprintf(policy_fp, "delete %s\n", policy);
-}
-
-static void stage_policy_io_test(void)
-{
- int i;
- policy_file = proc_policy_domain_policy;
- policy_fp = domain_fp;
- for (i = 0; i < 3; i++) {
- try_io("allow_chroot /", 1);
- try_io("allow_chroot ", 0);
- try_io("allow_chroot /mnt0/", 1);
- try_io("allow_chroot /var1/chroot2/", 1);
- try_io("allow_chroot /mnt0/", 1);
- try_io("allow_chroot /mnt0/", 1);
- try_io("allow_chroot /mnt0/", 1);
- try_io("allow_chroot /mnt\\?\\*/", 1);
- try_io("allow_chroot /mnt\\?\\*/", 1);
- try_io("allow_unmount /", 1);
- try_io("allow_unmount /sys1/", 1);
- try_io("allow_unmount /initrd2/", 1);
- try_io("allow_unmount /initrd/dev3/", 1);
- try_io("allow_unmount /initrd/\\*\\+/", 1);
- try_io("allow_unmount /initrd/\\@\\*/", 1);
- try_io("allow_unmount /initrd2/", 1);
- try_io("allow_pivot_root / /proc3/", 1);
- try_io("allow_pivot_root /sys5/ /proc3/", 1);
- try_io("allow_pivot_root /sys/", 0);
- try_io("allow_pivot_root *", 0);
- try_io("allow_pivot_root /sys5/ /proc3/", 1);
- try_io("allow_mount / / --bind 0xD", 1);
- try_io("allow_mount / / --move 0xF", 1);
- try_io("allow_mount / --remount", 0);
- try_io("allow_mount /", 0);
- try_io("allow_mount none /tmp/ tmpfs 0x1", 1);
- try_io("allow_mount none /tmp/ tmpfs", 0);
- try_io("allow_mount none /tmp/ nonexistent 0x0", 1);
- try_io("allow_mount none /proc/ proc 0x0", 1);
- try_io("allow_mount none /selinux/ selinuxfs 0x0", 1);
- try_io("allow_mount /proc/bus/usb /proc/bus/usb/ usbfs 0x0", 1);
- try_io("allow_mount none /dev/pts/ devpts 0x0", 1);
- try_io("allow_mount any / --remount 0xC00", 1);
- try_io("allow_mount /dev/sda1 /boot/ ext3 0xC00", 1);
- try_io("allow_mount none /dev/shm/ tmpfs 0x0", 1);
- try_io("allow_mount none /proc/sys/fs/binfmt_misc/ binfmt_misc "
- "0x0", 1);
- try_io("allow_mount none /proc/sys/fs/binfmt_misc/ binfmt_misc "
- "0x0 0x1", 0);
- try_io("allow_mount none /proc/sys/fs/binfmt_misc/ tmpfs "
- "binfmt_misc 0x0", 0);
- try_io("allow_mount /proc/bus/usb /proc/bus/usb/ usbfs 0x0", 1);
- }
- policy_file = proc_policy_exception_policy;
- policy_fp = exception_fp;
- for (i = 0; i < 3; i++) {
- try_io("allow_read /tmp/abc", 1);
- try_io("allow_read /tmp/abc\\*", 1);
- try_io("allow_read abc", 1);
- try_io("allow_read /tmp/abc/", 1);
- try_io("allow_read", 0);
- try_io("allow_read *", 1);
- try_io("file_pattern /\\*\\*\\*", 1);
- try_io("file_pattern /abc", 1);
- try_io("file_pattern /abc /def", 0);
- try_io("file_pattern abcdef", 1);
- try_io("path_group TEST /", 1);
- try_io("path_group TEST /boo", 1);
- try_io("path_group TEST /bar", 1);
- try_io("path_group TEST /\\*", 1);
- try_io("path_group TEST / /", 0);
- try_io("path_group TEST /boo", 1);
- try_io("path_group TEST /bar", 1);
- try_io("path_group TEST boo", 1);
- try_io("path_group TEST boo/", 1);
- try_io("path_group TEST /bar", 1);
- try_io("path_group TEST3 /\\*", 1);
- try_io("path_group TEST3 / /", 0);
- try_io("path_group TEST3 /boo", 1);
- try_io("path_group TEST3 /bar", 1);
- try_io("path_group TEST3 boo", 1);
- try_io("path_group TEST3 boo/", 1);
- try_io("deny_rewrite /", 1);
- try_io("deny_rewrite /foo", 1);
- try_io("deny_rewrite /\\*", 1);
- try_io("deny_rewrite /\\:", 0);
- try_io("deny_rewrite / /", 0);
- try_io("deny_rewrite @/TEST", 1);
- try_io("aggregator /boo/\\* /BOO", 1);
- try_io("aggregator /boo/\\* /BOO\\*", 0);
- try_io("aggregator /boo/\\*/ /BOO", 1);
- try_io("aggregator /boo/\\* /BOO/", 1);
- try_io("keep_domain <kernel>", 1);
- try_io("keep_domain <kernel> /sbin/init", 1);
- try_io("keep_domain <kernel> foo", 0);
- try_io("keep_domain <kernel> \\*", 0);
- try_io("keep_domain /ssh", 1);
- try_io("keep_domain /ssh /foo", 0);
- try_io("keep_domain /foo from <kernel>", 1);
- try_io("keep_domain /foo from <kernel> /sbin/init", 1);
- try_io("keep_domain from <kernel> /sbin/init", 0);
- try_io("keep_domain \\* from <kernel> /sbin/init", 0);
- try_io("no_keep_domain <kernel>", 1);
- try_io("no_keep_domain <kernel> /sbin/init", 1);
- try_io("no_keep_domain <kernel> foo", 0);
- try_io("no_keep_domain <kernel> \\*", 0);
- try_io("no_keep_domain /ssh", 1);
- try_io("no_keep_domain /ssh /foo", 0);
- try_io("no_keep_domain /foo from <kernel>", 1);
- try_io("no_keep_domain /foo from <kernel> /sbin/init", 1);
- try_io("no_keep_domain from <kernel> /sbin/init", 0);
- try_io("no_keep_domain \\* from <kernel> /sbin/init", 0);
- try_io("initialize_domain /foo", 1);
- try_io("initialize_domain /\\*", 1);
- try_io("initialize_domain /foo /bar", 0);
- try_io("initialize_domain /foo from /bar", 1);
- try_io("initialize_domain /foo from <kernel> /bar", 1);
- try_io("initialize_domain /\\* from <kernel>", 1);
- try_io("initialize_domain /foo from <kernel> \\*", 0);
- try_io("no_initialize_domain /foo", 1);
- try_io("no_initialize_domain /\\*", 1);
- try_io("no_initialize_domain /foo /bar", 0);
- try_io("no_initialize_domain /foo from /bar", 1);
- try_io("no_initialize_domain /foo from <kernel> /bar", 1);
- try_io("no_initialize_domain /\\* from <kernel>", 1);
- try_io("no_initialize_domain /foo from <kernel> \\*", 0);
- }
-}
-
-int main(void)
-{
- tomoyo_test_init();
- stage_policy_io_test();
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/tomoyo_policy_memory_test.c b/testcases/kernel/security/tomoyo/tomoyo_policy_memory_test.c
deleted file mode 100644
index a6620ba30..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_policy_memory_test.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_policy_memory_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-/*
- * Usage: Run this program using init= boot option.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mount.h>
-
-static void BUG(const char *msg)
-{
- printf("%s", msg);
- fflush(stdout);
- while (1)
- sleep(100);
-}
-
-static const char *policy_file = NULL;
-static const char *policy = NULL;
-
-static void get_meminfo(unsigned int *policy_memory)
-{
- FILE *fp = fopen("/sys/kernel/security/tomoyo/meminfo", "r");
- if (!fp || fscanf(fp, "Policy: %u", policy_memory) != 1 || fclose(fp))
- BUG("BUG: Policy read error\n");
-}
-
-static void check_policy_common(const int found_expected, const int id)
-{
- FILE *fp = fopen(policy_file, "r");
- char buffer[8192];
- int policy_found = 0;
- memset(buffer, 0, sizeof(buffer));
- if (!fp)
- BUG("BUG: Policy read error\n");
- while (fgets(buffer, sizeof(buffer) - 1, fp)) {
- char *cp = strchr(buffer, '\n');
- if (cp)
- *cp = '\0';
- if (strcmp(buffer, policy))
- continue;
- policy_found = 1;
- break;
- }
- fclose(fp);
- if (policy_found != found_expected) {
- printf("BUG: Policy write error: %s %s at %d\n", policy,
- found_expected ? "not added" : "not deleted", id);
- BUG("");
- }
-}
-
-static inline void check_policy_written(FILE * fp, const int id)
-{
- fflush(fp);
- check_policy_common(1, id);
-}
-
-static inline void check_policy_deleted(FILE * fp, const int id)
-{
- fflush(fp);
- check_policy_common(0, id);
-}
-
-static const char *domain_testcases[] = {
- "allow_create /tmp/mknod_reg_test 0600",
- "allow_create /tmp/open_test 0600",
- "allow_create /tmp/open_test 0600",
- "allow_create /tmp/open_test 0600",
- "allow_execute /bin/true",
- "allow_execute /bin/true",
- "allow_execute /bin/true0",
- "allow_execute /bin/true1",
- "allow_execute /bin/true2",
- "allow_execute /bin/true3",
- "allow_execute /bin/true4",
- "allow_execute /bin/true5",
- "allow_execute /bin/true6",
- "allow_execute /bin/true7",
- "allow_execute /bin/true7",
- "allow_execute /bin/true7",
- "allow_execute /bin/true8",
- "allow_ioctl socket:[family=2:type=2:protocol=17] 0-35122",
- "allow_ioctl socket:[family=2:type=2:protocol=17] 35122-35124",
- "allow_link /tmp/link_source_test /tmp/link_dest_test",
- "allow_mkblock /tmp/mknod_blk_test 0600 1 0",
- "allow_mkchar /tmp/mknod_chr_test 0600 1 3",
- "allow_mkdir /tmp/mkdir_test/ 0755",
- "allow_mkfifo /tmp/mknod_fifo_test 0600",
- "allow_mkfifo /tmp/mknod_fifo_test 0600",
- "allow_mksock /tmp/mknod_sock_test 0600",
- "allow_mksock /tmp/socket_test 0600",
- "allow_read /bin/true",
- "allow_read /bin/true",
- "allow_read /dev/null",
- "allow_read /dev/null",
- "allow_read /dev/null",
- "allow_read /dev/null",
- "allow_read /dev/null",
- "allow_read /dev/null",
- "allow_read /foo",
- "allow_read /proc/sys/net/ipv4/ip_local_port_range",
- "allow_read /proc/sys/net/ipv4/ip_local_port_range",
- "allow_read/write /bar",
- "allow_read/write /dev/null",
- "allow_read/write /dev/null",
- "allow_read/write /proc/sys/net/ipv4/ip_local_port_range",
- "allow_read/write /proc/sys/net/ipv4/ip_local_port_range",
- "allow_read/write /tmp/fifo",
- "allow_read/write /tmp/fifo",
- "allow_read/write /tmp/rewrite_test",
- "allow_rename /tmp/rename_source_test /tmp/rename_dest_test",
- "allow_rmdir /tmp/rmdir_test/",
- "allow_symlink /symlink",
- "allow_symlink /symlink",
- "allow_symlink /symlink",
- "allow_symlink /symlink",
- "allow_symlink /tmp/symlink_source_test",
- "allow_symlink /tmp/symlink_source_test",
- "allow_symlink /tmp/symlink_source_test",
- "allow_symlink /tmp/symlink_source_test",
- "allow_symlink /tmp/symlink_source_test",
- "allow_truncate /tmp/rewrite_test",
- "allow_truncate /tmp/truncate_test",
- "allow_truncate /tmp/truncate_test",
- "allow_unlink /tmp/unlink_test",
- "allow_write /123",
- "allow_write /dev/null",
- "allow_write /dev/null",
- "allow_write /devfile",
- "allow_write /devfile",
- "allow_write /proc/sys/net/ipv4/ip_local_port_range",
- "allow_write /proc/sys/net/ipv4/ip_local_port_range",
- "allow_write /tmp/open_test",
- "allow_write /tmp/open_test",
- "allow_write /tmp/open_test",
- "allow_write /tmp/truncate_test",
- "allow_write /tmp/truncate_test",
- "allow_rewrite /tmp/rewrite_test",
- "allow_rewrite /tmp/rewrite_test",
- "allow_mount /dev/sda1 /mnt/sda1/ ext3 0x123",
- "allow_mount /dev/sda1 /mnt/sda1/ ext3 123",
- "allow_mount /dev/sda1 /mnt/sda1/ ext3 0123",
- "allow_mount /dev/sda1 /mnt/sda1/ ext3 0x123",
- "allow_mount /dev/sda1 /mnt/sda1/ ext3 123",
- "allow_mount /dev/sda1 /mnt/sda1/ ext3 0123",
- "allow_chroot /",
- "allow_chroot /",
- "allow_chroot /mnt/",
- "allow_pivot_root / /proc/",
- "allow_pivot_root /mnt/ /proc/mnt/",
- "allow_unmount /",
- "allow_unmount /proc/",
- NULL
-};
-
-static void domain_policy_test(const unsigned int before)
-{
- unsigned int after;
- int j;
- policy_file = "/sys/kernel/security/tomoyo/domain_policy";
- for (j = 0; domain_testcases[j]; j++) {
- int i;
- FILE *fp = fopen(policy_file, "w");
- if (!fp)
- BUG("BUG: Policy write error\n");
- fprintf(fp, "<kernel>\n");
- policy = domain_testcases[j];
- printf("Processing: %s\n", policy);
- for (i = 0; i < 100; i++) {
- fprintf(fp, "%s\n", policy);
- if (!i)
- check_policy_written(fp, 1);
- fprintf(fp, "delete %s\n", policy);
- }
- check_policy_deleted(fp, 1);
- for (i = 0; i < 100; i++)
- fprintf(fp, "%s\n", policy);
- check_policy_written(fp, 2);
- fprintf(fp, "delete %s\n", policy);
- check_policy_deleted(fp, 2);
- fclose(fp);
- for (i = 0; i < 30; i++) {
- usleep(100000);
- get_meminfo(&after);
- if (before == after)
- break;
- }
- if (before != after) {
- printf("Policy: %d\n", after - before);
- BUG("Policy read/write test: Fail\n");
- }
- }
- for (j = 0; j < 10; j++) {
- int i;
- FILE *fp = fopen(policy_file, "w");
- if (!fp)
- BUG("BUG: Policy write error\n");
- fprintf(fp, "<kernel> /sbin/init\n");
- for (i = 0; domain_testcases[i]; i++)
- fprintf(fp, "%s\n", domain_testcases[i]);
- fprintf(fp, "delete <kernel> /sbin/init\n");
- fclose(fp);
- for (i = 0; i < 50; i++) {
- usleep(100000);
- get_meminfo(&after);
- if (before == after)
- break;
- }
- if (before != after) {
- printf("Policy: %d\n", after - before);
- BUG("Policy read/write test: Fail\n");
- }
- }
-}
-
-static const char *exception_testcases[] = {
- "allow_read /tmp/mknod_reg_test",
- "allow_env HOME",
- "path_group PG1 /",
- "path_group PG2 /",
- "address_group AG3 0.0.0.0",
- "address_group AG3 1.2.3.4-5.6.7.8",
- "address_group AG3 f:ee:ddd:cccc:b:aa:999:8888",
- "address_group AG4 0:1:2:3:4:5:6:7-8:90:a00:b000:c00:d0:e:f000",
- "number_group NG1 1000",
- "number_group NG2 10-0x100000",
- "number_group NG3 01234567-0xABCDEF89",
- "deny_autobind 1024",
- "deny_autobind 32668-65535",
- "deny_autobind 0-1023",
- "initialize_domain /usr/sbin/sshd",
- "no_initialize_domain /usr/sbin/sshd",
- "initialize_domain /usr/sbin/sshd from /bin/bash",
- "no_initialize_domain /usr/sbin/sshd from /bin/bash",
- "initialize_domain /usr/sbin/sshd from "
- "<kernel> /bin/mingetty/bin/bash",
- "no_initialize_domain /usr/sbin/sshd from "
- "<kernel> /bin/mingetty/bin/bash",
- "keep_domain <kernel> /usr/sbin/sshd /bin/bash",
- "no_keep_domain <kernel> /usr/sbin/sshd /bin/bash",
- "keep_domain /bin/pwd from <kernel> /usr/sbin/sshd /bin/bash",
- "no_keep_domain /bin/pwd from <kernel> /usr/sbin/sshd /bin/bash",
- "keep_domain /bin/pwd from /bin/bash",
- "no_keep_domain /bin/pwd from /bin/bash",
- "file_pattern /proc/\\$/task/\\$/environ",
- "file_pattern /proc/\\$/task/\\$/auxv",
- "allow_read /etc/ld.so.cache",
- "allow_read /proc/meminfo",
- "allow_read /proc/sys/kernel/version",
- "allow_read /etc/localtime",
- "allow_read /proc/self/task/\\$/attr/current",
- "allow_read /proc/self/task/\\$/oom_score",
- "allow_read /proc/self/wchan",
- "allow_read /lib/ld-2.5.so",
- "file_pattern pipe:[\\$]",
- "file_pattern socket:[\\$]",
- "file_pattern /var/cache/logwatch/logwatch.\\*/",
- "file_pattern /var/cache/logwatch/logwatch.\\*/\\*",
- "deny_rewrite /var/log/\\*",
- "deny_rewrite /var/log/\\*/\\*",
- "aggregator /etc/rc.d/rc\\?.d/\\?\\+\\+smb /etc/rc.d/init.d/smb",
- "aggregator /etc/rc.d/rc\\?.d/\\?\\+\\+crond /etc/rc.d/init.d/crond",
- NULL
-};
-
-static void exception_policy_test(const unsigned int before)
-{
- unsigned int after;
- int j;
- policy_file = "/sys/kernel/security/tomoyo/exception_policy";
- for (j = 0; exception_testcases[j]; j++) {
- int i;
- FILE *fp = fopen(policy_file, "w");
- if (!fp)
- BUG("BUG: Policy write error\n");
- policy = exception_testcases[j];
- printf("Processing: %s\n", policy);
- for (i = 0; i < 100; i++) {
- fprintf(fp, "%s\n", policy);
- if (!i)
- check_policy_written(fp, 1);
- fprintf(fp, "delete %s\n", policy);
- }
- check_policy_deleted(fp, 1);
- for (i = 0; i < 100; i++)
- fprintf(fp, "%s\n", policy);
- check_policy_written(fp, 2);
- fprintf(fp, "delete %s\n", policy);
- check_policy_deleted(fp, 2);
- fclose(fp);
- for (i = 0; i < 30; i++) {
- usleep(100000);
- get_meminfo(&after);
- if (before == after)
- break;
- }
- if (before != after) {
- printf("Policy: %d\n", after - before);
- BUG("Policy read/write test: Fail\n");
- }
- }
- for (j = 0; j < 10; j++) {
- int i;
- FILE *fp = fopen(policy_file, "w");
- if (!fp)
- BUG("BUG: Policy write error\n");
- for (i = 0; exception_testcases[i]; i++)
- fprintf(fp, "%s\n", exception_testcases[i]);
- for (i = 0; exception_testcases[i]; i++)
- fprintf(fp, "delete %s\n", exception_testcases[i]);
- fclose(fp);
- for (i = 0; i < 50; i++) {
- usleep(100000);
- get_meminfo(&after);
- if (before == after)
- break;
- }
- if (before != after) {
- printf("Policy: %d\n", after - before);
- BUG("Policy read/write test: Fail\n");
- }
- }
-}
-
-int main(void)
-{
- unsigned int before;
- mount("/proc", "/proc/", "proc", 0, NULL);
- get_meminfo(&before);
- domain_policy_test(before);
- exception_policy_test(before);
- BUG("Policy read/write test: Success\n");
- return 0;
-}
diff --git a/testcases/kernel/security/tomoyo/tomoyo_rewrite_test.c b/testcases/kernel/security/tomoyo/tomoyo_rewrite_test.c
deleted file mode 100644
index 7bc22c39b..000000000
--- a/testcases/kernel/security/tomoyo/tomoyo_rewrite_test.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/******************************************************************************/
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/*
- * tomoyo_rewrite_test.c
- *
- * Testing program for security/tomoyo/
- *
- * Copyright (C) 2005-2010 NTT DATA CORPORATION
- */
-#include "include.h"
-
-static int should_fail = 0;
-
-static void show_prompt(const char *str)
-{
- printf("Testing %35s: (%s) ", str,
- should_fail ? "must fail" : "must success");
- errno = 0;
-}
-
-static void show_result(int result)
-{
- if (should_fail) {
- if (result == EOF) {
- if (errno == EPERM)
- printf("OK: Permission denied.\n");
- else
- printf("BUG!\n");
- } else {
- printf("BUG!\n");
- }
- } else {
- if (result != EOF)
- printf("OK\n");
- else
- printf("BUG!\n");
- }
-}
-
-#define REWRITE_PATH "/tmp/rewrite_test"
-
-static void stage_rewrite_test(void)
-{
- int fd;
-
- /* Start up */
- write_domain_policy("allow_read/write " REWRITE_PATH, 0);
- write_domain_policy("allow_truncate " REWRITE_PATH, 0);
- write_domain_policy("allow_create " REWRITE_PATH " 0600", 0);
- write_domain_policy("allow_unlink " REWRITE_PATH, 0);
- write_exception_policy("deny_rewrite " REWRITE_PATH, 0);
- set_profile(3, "file::open");
- set_profile(3, "file::create");
- set_profile(3, "file::truncate");
- set_profile(3, "file::rewrite");
- set_profile(3, "file::unlink");
- close(open(REWRITE_PATH, O_WRONLY | O_APPEND | O_CREAT, 0600));
-
- /* Enforce mode */
- should_fail = 0;
-
- show_prompt("open(O_RDONLY)");
- fd = open(REWRITE_PATH, O_RDONLY);
- show_result(fd);
- close(fd);
-
- show_prompt("open(O_WRONLY | O_APPEND)");
- fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
- show_result(fd);
- close(fd);
-
- should_fail = 1;
- show_prompt("open(O_WRONLY)");
- fd = open(REWRITE_PATH, O_WRONLY);
- show_result(fd);
- close(fd);
-
- show_prompt("open(O_WRONLY | O_TRUNC)");
- fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC);
- show_result(fd);
- close(fd);
-
- show_prompt("open(O_WRONLY | O_TRUNC | O_APPEND)");
- fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC | O_APPEND);
- show_result(fd);
- close(fd);
-
- show_prompt("truncate()");
- show_result(truncate(REWRITE_PATH, 0));
-
- fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
- show_prompt("ftruncate()");
- show_result(ftruncate(fd, 0));
-
- show_prompt("fcntl(F_SETFL, ~O_APPEND)");
- show_result(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_APPEND));
- close(fd);
-
- /* Permissive mode */
- set_profile(2, "file::open");
- set_profile(2, "file::create");
- set_profile(2, "file::truncate");
- set_profile(2, "file::rewrite");
- set_profile(2, "file::unlink");
- should_fail = 0;
-
- show_prompt("open(O_RDONLY)");
- fd = open(REWRITE_PATH, O_RDONLY);
- show_result(fd);
- close(fd);
-
- show_prompt("open(O_WRONLY | O_APPEND)");
- fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
- show_result(fd);
- close(fd);
-
- show_prompt("open(O_WRONLY)");
- fd = open(REWRITE_PATH, O_WRONLY);
- show_result(fd);
- close(fd);
-
- show_prompt("open(O_WRONLY | O_TRUNC)");
- fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC);
- show_result(fd);
- close(fd);
-
- show_prompt("open(O_WRONLY | O_TRUNC | O_APPEND)");
- fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC | O_APPEND);
- show_result(fd);
- close(fd);
-
- show_prompt("truncate()");
- show_result(truncate(REWRITE_PATH, 0));
-
- fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
- show_prompt("ftruncate()");
- show_result(ftruncate(fd, 0));
-
- show_prompt("fcntl(F_SETFL, ~O_APPEND)");
- show_result(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_APPEND));
- close(fd);
-
- /* Clean up */
- unlink(REWRITE_PATH);
- write_exception_policy("deny_rewrite " REWRITE_PATH, 0);
- printf("\n\n");
-}
-
-int main(void)
-{
- tomoyo_test_init();
- stage_rewrite_test();
- clear_status();
- return 0;
-}
diff --git a/testcases/kernel/sound/snd_timer01.c b/testcases/kernel/sound/snd_timer01.c
index 123d1a2cb..310169b0f 100644
--- a/testcases/kernel/sound/snd_timer01.c
+++ b/testcases/kernel/sound/snd_timer01.c
@@ -8,7 +8,7 @@
*
* The test performs several ioctl() parallel with readv() on the same
* file descriptor to /dev/snd/timer. A buggy kernel will leak memory
- * to the process, which may contain information from the the kernel or
+ * to the process, which may contain information from the kernel or
* any other process on the system.
*
* The issue was fixed with
diff --git a/testcases/kernel/syscalls/access/access01.c b/testcases/kernel/syscalls/access/access01.c
index c9a076dfe..391c8d44b 100644
--- a/testcases/kernel/syscalls/access/access01.c
+++ b/testcases/kernel/syscalls/access/access01.c
@@ -1,11 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- * AUTHOR : William Roske
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: William Roske
*/
-/*
+
+/*\
+ * [Description]
+ *
* Basic test for access(2) using F_OK, R_OK, W_OK and X_OK
*/
+
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
diff --git a/testcases/kernel/syscalls/access/access02.c b/testcases/kernel/syscalls/access/access02.c
index bf636f9f4..c8fe0d0dc 100644
--- a/testcases/kernel/syscalls/access/access02.c
+++ b/testcases/kernel/syscalls/access/access02.c
@@ -1,21 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) Guangwen Feng <fenggw-fnst@cn.fujitsu.com>, 2016
+ * Copyright (c) Linux Test Project, 2002-2023
+ * Ported to LTP: Wayne Boyer
*/
-/*
- * Test Description:
- * Verify that access() succeeds to check the existence or read/write/execute
- * permissions on a file if the mode argument passed was F_OK/R_OK/W_OK/X_OK.
+/*\
+ * [Description]
*
- * Also verify that, access() succeeds to test the accessibility of the file
- * referred to by symbolic link if the pathname points to a symbolic link.
+ * Test access(2) syscall
*
- * As well as verify that, these test files can be
- * stat/read/written/executed indeed as root and nobody respectively.
- *
- * Ported to LTP: Wayne Boyer
- * 06/2016 Modified by Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ * - check the existence or read/write/execute permissions on a file (mode argument: F_OK/R_OK/W_OK/X_OK)
+ * - test the accessibility of the file referred to by symbolic link if the pathname points to a symbolic link
+ * - file can be stat/read/written/executed as root and nobody
*/
#include <sys/types.h>
diff --git a/testcases/kernel/syscalls/access/access03.c b/testcases/kernel/syscalls/access/access03.c
index ae3f676b1..7cae1ec2e 100644
--- a/testcases/kernel/syscalls/access/access03.c
+++ b/testcases/kernel/syscalls/access/access03.c
@@ -1,9 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2003-2023
*/
-/*
+/*\
+ * [Description]
+ *
* access(2) test for errno(s) EFAULT as root and nobody respectively.
*/
diff --git a/testcases/kernel/syscalls/access/access04.c b/testcases/kernel/syscalls/access/access04.c
index 2d6dd70e8..b5764a5dd 100644
--- a/testcases/kernel/syscalls/access/access04.c
+++ b/testcases/kernel/syscalls/access/access04.c
@@ -2,26 +2,27 @@
/*
* Copyright (c) International Business Machines Corp., 2001
* Copyright (c) 2013 Fujitsu Ltd.
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Ported to LTP: Wayne Boyer
+ * 11/2013 Ported by Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com>
+ * 11/2016 Modified by Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
*/
-/*
- * Verify that,
- * 1) access() fails with -1 return value and sets errno to EINVAL
- * if the specified access mode argument is invalid.
- * 2) access() fails with -1 return value and sets errno to ENOENT
- * if the specified file doesn't exist (or pathname is NULL).
- * 3) access() fails with -1 return value and sets errno to ENAMETOOLONG
- * if the pathname size is > PATH_MAX characters.
- * 4) access() fails with -1 return value and sets errno to ENOTDIR
- * if a component used as a directory in pathname is not a directory.
- * 5) access() fails with -1 return value and sets errno to ELOOP
- * if too many symbolic links were encountered in resolving pathname.
- * 6) access() fails with -1 return value and sets errno to EROFS
- * if write permission was requested for files on a read-only file system.
+/*\
+ * [Description]
*
- * Ported to LTP: Wayne Boyer
- * 11/2013 Ported by Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com>
- * 11/2016 Modified by Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ * - access() fails with -1 return value and sets errno to EINVAL
+ * if the specified access mode argument is invalid.
+ * - access() fails with -1 return value and sets errno to ENOENT
+ * if the specified file doesn't exist (or pathname is NULL).
+ * - access() fails with -1 return value and sets errno to ENAMETOOLONG
+ * if the pathname size is > PATH_MAX characters.
+ * - access() fails with -1 return value and sets errno to ENOTDIR
+ * if a component used as a directory in pathname is not a directory.
+ * - access() fails with -1 return value and sets errno to ELOOP
+ * if too many symbolic links were encountered in resolving pathname.
+ * - access() fails with -1 return value and sets errno to EROFS
+ * if write permission was requested for files on a read-only file system.
*/
#include <errno.h>
@@ -39,26 +40,32 @@
#define SNAME1 "symlink1"
#define SNAME2 "symlink2"
#define MNT_POINT "mntpoint"
+#define LONGPATHSIZE (PATH_MAX + 2)
static uid_t uid;
-static char longpathname[PATH_MAX + 2];
+static char *longpathname;
+static char *fname1;
+static char *fname2;
+static char *sname1;
+static char *empty_fname;
+static char *mnt_point;
static struct tcase {
- const char *pathname;
+ char **pathname;
int mode;
int exp_errno;
} tcases[] = {
- {FNAME1, -1, EINVAL},
- {"", W_OK, ENOENT},
- {longpathname, R_OK, ENAMETOOLONG},
- {FNAME2, R_OK, ENOTDIR},
- {SNAME1, R_OK, ELOOP},
- {MNT_POINT, W_OK, EROFS}
+ {&fname1, -1, EINVAL},
+ {&empty_fname, W_OK, ENOENT},
+ {&longpathname, R_OK, ENAMETOOLONG},
+ {&fname2, R_OK, ENOTDIR},
+ {&sname1, R_OK, ELOOP},
+ {&mnt_point, W_OK, EROFS}
};
static void access_test(struct tcase *tc, const char *user)
{
- TST_EXP_FAIL(access(tc->pathname, tc->mode), tc->exp_errno,
+ TST_EXP_FAIL(access(*tc->pathname, tc->mode), tc->exp_errno,
"access as %s", user);
}
@@ -86,7 +93,8 @@ static void setup(void)
uid = pw->pw_uid;
- memset(longpathname, 'a', sizeof(longpathname) - 1);
+ memset(longpathname, 'a', LONGPATHSIZE - 1);
+ longpathname[LONGPATHSIZE-1] = 0;
SAFE_TOUCH(FNAME1, 0333, NULL);
SAFE_TOUCH(DNAME, 0644, NULL);
@@ -103,4 +111,13 @@ static struct tst_test test = {
.mntpoint = MNT_POINT,
.setup = setup,
.test = verify_access,
+ .bufs = (struct tst_buffers []) {
+ {&fname1, .str = FNAME1},
+ {&fname2, .str = FNAME2},
+ {&sname1, .str = SNAME1},
+ {&empty_fname, .str = ""},
+ {&longpathname, .size = LONGPATHSIZE},
+ {&mnt_point, .str = MNT_POINT},
+ {}
+ }
};
diff --git a/testcases/kernel/syscalls/acct/acct01.c b/testcases/kernel/syscalls/acct/acct01.c
index 254d7b503..52c4d41da 100644
--- a/testcases/kernel/syscalls/acct/acct01.c
+++ b/testcases/kernel/syscalls/acct/acct01.c
@@ -27,17 +27,25 @@
#define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
S_IXGRP|S_IROTH|S_IXOTH)
#define FILE_EISDIR "."
-#define FILE_EACCES "/dev/null"
+#define FILE_EACCESS "/dev/null"
#define FILE_ENOENT "/tmp/does/not/exist"
#define FILE_ENOTDIR "./tmpfile/"
-#define TEST_TMPFILE "./tmpfile"
-#define TEST_ELOOP "test_file_eloop1"
-#define TEST_ENAMETOOLONG nametoolong
-#define TEST_EROFS "mntpoint/file"
+#define FILE_TMPFILE "./tmpfile"
+#define FILE_ELOOP "test_file_eloop1"
+#define FILE_EROFS "ro_mntpoint/file"
-static char nametoolong[PATH_MAX+2];
static struct passwd *ltpuser;
+static char *file_eisdir;
+static char *file_eaccess;
+static char *file_enoent;
+static char *file_enotdir;
+static char *file_tmpfile;
+static char *file_eloop;
+static char *file_enametoolong;
+static char *file_erofs;
+static char *file_null;
+
static void setup_euid(void)
{
SAFE_SETEUID(ltpuser->pw_uid);
@@ -49,21 +57,21 @@ static void cleanup_euid(void)
}
static struct test_case {
- char *filename;
- char *exp_errval;
+ char **filename;
+ char *desc;
int exp_errno;
void (*setupfunc) ();
void (*cleanfunc) ();
} tcases[] = {
- {FILE_EISDIR, "EISDIR", EISDIR, NULL, NULL},
- {FILE_EACCES, "EACCES", EACCES, NULL, NULL},
- {FILE_ENOENT, "ENOENT", ENOENT, NULL, NULL},
- {FILE_ENOTDIR, "ENOTDIR", ENOTDIR, NULL, NULL},
- {TEST_TMPFILE, "EPERM", EPERM, setup_euid, cleanup_euid},
- {NULL, "EPERM", EPERM, setup_euid, cleanup_euid},
- {TEST_ELOOP, "ELOOP", ELOOP, NULL, NULL},
- {TEST_ENAMETOOLONG, "ENAMETOOLONG", ENAMETOOLONG, NULL, NULL},
- {TEST_EROFS, "EROFS", EROFS, NULL, NULL},
+ {&file_eisdir, FILE_EISDIR, EISDIR, NULL, NULL},
+ {&file_eaccess, FILE_EACCESS, EACCES, NULL, NULL},
+ {&file_enoent, FILE_ENOENT, ENOENT, NULL, NULL},
+ {&file_enotdir, FILE_ENOTDIR, ENOTDIR, NULL, NULL},
+ {&file_tmpfile, FILE_TMPFILE, EPERM, setup_euid, cleanup_euid},
+ {&file_null, "NULL", EPERM, setup_euid, cleanup_euid},
+ {&file_eloop, FILE_ELOOP, ELOOP, NULL, NULL},
+ {&file_enametoolong, "aaaa...", ENAMETOOLONG, NULL, NULL},
+ {&file_erofs, FILE_EROFS, EROFS, NULL, NULL},
};
static void setup(void)
@@ -76,10 +84,10 @@ static void setup(void)
ltpuser = SAFE_GETPWNAM("nobody");
- fd = SAFE_CREAT(TEST_TMPFILE, 0777);
+ fd = SAFE_CREAT(FILE_TMPFILE, 0777);
SAFE_CLOSE(fd);
- TEST(acct(TEST_TMPFILE));
+ TEST(acct(FILE_TMPFILE));
if (TST_RET == -1)
tst_brk(TBROK | TTERRNO, "acct failed unexpectedly");
@@ -89,11 +97,11 @@ static void setup(void)
tst_brk(TBROK | TTERRNO, "acct(NULL) failed");
/* ELOOP SETTING */
- SAFE_SYMLINK(TEST_ELOOP, "test_file_eloop2");
- SAFE_SYMLINK("test_file_eloop2", TEST_ELOOP);
+ SAFE_SYMLINK(FILE_ELOOP, "test_file_eloop2");
+ SAFE_SYMLINK("test_file_eloop2", FILE_ELOOP);
- /* ENAMETOOLONG SETTING */
- memset(nametoolong, 'a', PATH_MAX+1);
+ memset(file_enametoolong, 'a', PATH_MAX+1);
+ file_enametoolong[PATH_MAX+1] = 0;
}
static void verify_acct(unsigned int nr)
@@ -103,31 +111,29 @@ static void verify_acct(unsigned int nr)
if (tcase->setupfunc)
tcase->setupfunc();
- TEST(acct(tcase->filename));
+ TST_EXP_FAIL(acct(*tcase->filename), tcase->exp_errno,
+ "acct(%s)", tcase->desc);
if (tcase->cleanfunc)
tcase->cleanfunc();
-
- if (TST_RET != -1) {
- tst_res(TFAIL, "acct(%s) succeeded unexpectedly",
- tcase->filename);
- return;
- }
-
- if (TST_ERR == tcase->exp_errno) {
- tst_res(TPASS | TTERRNO, "acct() failed as expected");
- } else {
- tst_res(TFAIL | TTERRNO,
- "acct() failed, expected: %s",
- tst_strerrno(tcase->exp_errno));
- }
}
static struct tst_test test = {
.needs_root = 1,
- .mntpoint = "mntpoint",
+ .mntpoint = "ro_mntpoint",
.needs_rofs = 1,
.tcnt = ARRAY_SIZE(tcases),
.setup = setup,
.test = verify_acct,
+ .bufs = (struct tst_buffers []) {
+ {&file_eisdir, .str = FILE_EISDIR},
+ {&file_eaccess, .str = FILE_EACCESS},
+ {&file_enoent, .str = FILE_ENOENT},
+ {&file_enotdir, .str = FILE_ENOTDIR},
+ {&file_tmpfile, .str = FILE_TMPFILE},
+ {&file_eloop, .str = FILE_ELOOP},
+ {&file_enametoolong, .size = PATH_MAX+2},
+ {&file_erofs, .str = FILE_EROFS},
+ {}
+ }
};
diff --git a/testcases/kernel/syscalls/adjtimex/adjtimex02.c b/testcases/kernel/syscalls/adjtimex/adjtimex02.c
index dab640ff3..e66ba2a5c 100644
--- a/testcases/kernel/syscalls/adjtimex/adjtimex02.c
+++ b/testcases/kernel/syscalls/adjtimex/adjtimex02.c
@@ -14,11 +14,6 @@
* - EFAULT with SET_MODE and invalid timex pointer
* - EINVAL with ADJ_TICK greater than max tick
* - EINVAL with ADJ_TICK smaller than min tick
- *
- * On kernels older than 2.6.26:
- *
- * - EINVAL with AJD_OFFSET smaller than min offset
- * - EINVAL with AJD_OFFSET greater than max offset
*/
#include <errno.h>
@@ -57,8 +52,6 @@ static struct test_case {
{.modes = SET_MODE, .exp_err = EFAULT},
{.modes = ADJ_TICK, .lowlimit = 900000, .delta = 1, .exp_err = EINVAL},
{.modes = ADJ_TICK, .highlimit = 1100000, .delta = 1, .exp_err = EINVAL},
- {.modes = ADJ_OFFSET, .highlimit = 512000L, .delta = 1, .exp_err = EINVAL},
- {.modes = ADJ_OFFSET, .lowlimit = -512000L, .delta = -1, .exp_err = EINVAL},
};
static struct test_variants
@@ -93,12 +86,6 @@ static void verify_adjtimex(unsigned int i)
if (tc[i].highlimit)
buf->tick = tc[i].highlimit + tc[i].delta;
}
- if (tc[i].modes == ADJ_OFFSET) {
- if (tc[i].lowlimit || tc[i].highlimit) {
- tst_res(TCONF, "Newer kernels normalize offset value outside range");
- return;
- }
- }
}
if (tc[i].exp_err == EFAULT) {
diff --git a/testcases/kernel/syscalls/adjtimex/adjtimex03.c b/testcases/kernel/syscalls/adjtimex/adjtimex03.c
index 333cabf11..7056973cc 100644
--- a/testcases/kernel/syscalls/adjtimex/adjtimex03.c
+++ b/testcases/kernel/syscalls/adjtimex/adjtimex03.c
@@ -1,14 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) Zilogic Systems Pvt. Ltd, 2020. All Rights Reserved.
- * Email: <code@zilogic.com>
+ * Copyright (c) Zilogic Systems Pvt. Ltd <code@zilogic.com>, 2020
+ * Copyright (c) Linux Test Project, 2021-2023
*
* Based on testcases/kernel/syscalls/adjtimex/adjtimex01.c
* Copyright (c) Wipro Technologies Ltd, 2002.
+ */
+
+/*\
+ * [Description]
*
- * CVE-2018-11508
- *
- * Test 4-byte kernel data leak via adjtimex
+ * CVE-2018-11508: Test 4-byte kernel data leak via adjtimex.
*
* On calling the adjtimex() function call with invalid mode (let's say
* 0x8000), ideally all the parameters should return with null data. But,
@@ -64,6 +66,7 @@ void verify_adjtimex(void)
break;
}
}
+
if (data_leak != 0)
tst_res(TFAIL, "Data leak observed");
else
diff --git a/testcases/kernel/syscalls/alarm/alarm02.c b/testcases/kernel/syscalls/alarm/alarm02.c
index b2fde03c8..fcf70c5f3 100644
--- a/testcases/kernel/syscalls/alarm/alarm02.c
+++ b/testcases/kernel/syscalls/alarm/alarm02.c
@@ -9,6 +9,7 @@
* [Description]
*
* Verify that alarm() returns:
+ *
* - zero when there was no previously scheduled alarm
* - number of seconds remaining until any previously scheduled alarm
*/
diff --git a/testcases/kernel/syscalls/bind/bind03.c b/testcases/kernel/syscalls/bind/bind03.c
index 37a040b29..8c95cd799 100644
--- a/testcases/kernel/syscalls/bind/bind03.c
+++ b/testcases/kernel/syscalls/bind/bind03.c
@@ -43,8 +43,12 @@ static void run(void)
* locks the socket and does all the checks and the node is not removed
* in the error path. For now we will unlink the node here so that the
* test works fine when the run() function is executed in a loop.
+ * From v5.14-rc1 the kernel has fix above issue.
*/
- unlink(SNAME_B);
+ if (tst_kvercmp(5, 14, 0) >= 0)
+ TST_EXP_FAIL(unlink(SNAME_B), ENOENT, "check exist of SNAME_B");
+ else
+ unlink(SNAME_B);
}
static void setup(void)
diff --git a/testcases/kernel/syscalls/bpf/bpf_common.h b/testcases/kernel/syscalls/bpf/bpf_common.h
index 39764ba1f..a0800d19b 100644
--- a/testcases/kernel/syscalls/bpf/bpf_common.h
+++ b/testcases/kernel/syscalls/bpf/bpf_common.h
@@ -13,6 +13,7 @@
#include "lapi/socket.h"
#define BPF_MEMLOCK_ADD (2*1024*1024)
+#define BUFSIZE 8192
/* map[array_indx] = reg_to_save
*
diff --git a/testcases/kernel/syscalls/bpf/bpf_prog01.c b/testcases/kernel/syscalls/bpf/bpf_prog01.c
index e2fc80a9f..de4f68cef 100644
--- a/testcases/kernel/syscalls/bpf/bpf_prog01.c
+++ b/testcases/kernel/syscalls/bpf/bpf_prog01.c
@@ -63,7 +63,7 @@ int load_prog(int fd)
BPF_EXIT_INSN(), /* return r0 */
};
- bpf_init_prog_attr(attr, PROG, sizeof(PROG), log, BUFSIZ);
+ bpf_init_prog_attr(attr, PROG, sizeof(PROG), log, BUFSIZE);
return bpf_load_prog(attr, log);
}
diff --git a/testcases/kernel/syscalls/bpf/bpf_prog02.c b/testcases/kernel/syscalls/bpf/bpf_prog02.c
index b40ea0f1d..fd3e535c1 100644
--- a/testcases/kernel/syscalls/bpf/bpf_prog02.c
+++ b/testcases/kernel/syscalls/bpf/bpf_prog02.c
@@ -64,7 +64,7 @@ static int load_prog(int fd)
BPF_EXIT_INSN(), /* 26: return r0 */
};
- bpf_init_prog_attr(attr, insn, sizeof(insn), log, BUFSIZ);
+ bpf_init_prog_attr(attr, insn, sizeof(insn), log, BUFSIZE);
return bpf_load_prog(attr, log);
}
@@ -117,7 +117,7 @@ static struct tst_test test = {
.bufs = (struct tst_buffers []) {
{&key, .size = sizeof(*key)},
{&val, .size = sizeof(*val)},
- {&log, .size = BUFSIZ},
+ {&log, .size = BUFSIZE},
{&attr, .size = sizeof(*attr)},
{&msg, .size = sizeof(MSG)},
{},
diff --git a/testcases/kernel/syscalls/bpf/bpf_prog04.c b/testcases/kernel/syscalls/bpf/bpf_prog04.c
index ebee26cbc..cf3bb1254 100644
--- a/testcases/kernel/syscalls/bpf/bpf_prog04.c
+++ b/testcases/kernel/syscalls/bpf/bpf_prog04.c
@@ -28,7 +28,6 @@
#include "tst_capability.h"
#include "bpf_common.h"
-#define BUFSIZE 8192
#define CHECK_BPF_RET(x) ((x) >= 0 || ((x) == -1 && errno != EACCES))
static const char MSG[] = "Ahoj!";
diff --git a/testcases/kernel/syscalls/bpf/bpf_prog05.c b/testcases/kernel/syscalls/bpf/bpf_prog05.c
index 2be5a2cc9..742beab0b 100644
--- a/testcases/kernel/syscalls/bpf/bpf_prog05.c
+++ b/testcases/kernel/syscalls/bpf/bpf_prog05.c
@@ -52,8 +52,6 @@
#include "tst_capability.h"
#include "bpf_common.h"
-#define BUFSIZE 8192
-
static const char MSG[] = "Ahoj!";
static char *msg;
diff --git a/testcases/kernel/syscalls/bpf/bpf_prog06.c b/testcases/kernel/syscalls/bpf/bpf_prog06.c
index c38dd8239..cee9616cf 100644
--- a/testcases/kernel/syscalls/bpf/bpf_prog06.c
+++ b/testcases/kernel/syscalls/bpf/bpf_prog06.c
@@ -46,8 +46,6 @@
#include "lapi/bpf.h"
#include "bpf_common.h"
-#define BUFSIZE 8192
-
static const char MSG[] = "Ahoj!";
static char *msg;
diff --git a/testcases/kernel/syscalls/bpf/bpf_prog07.c b/testcases/kernel/syscalls/bpf/bpf_prog07.c
index 50ff6eed0..dab5bb8ad 100644
--- a/testcases/kernel/syscalls/bpf/bpf_prog07.c
+++ b/testcases/kernel/syscalls/bpf/bpf_prog07.c
@@ -46,8 +46,6 @@
#include "lapi/bpf.h"
#include "bpf_common.h"
-#define BUFSIZE 8192
-
static const char MSG[] = "Ahoj!";
static char *msg;
diff --git a/testcases/kernel/syscalls/capset/capset01.c b/testcases/kernel/syscalls/capset/capset01.c
index a323fc5be..25db8112c 100644
--- a/testcases/kernel/syscalls/capset/capset01.c
+++ b/testcases/kernel/syscalls/capset/capset01.c
@@ -1,12 +1,20 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
- * AUTHOR : Saji Kumar.V.R <saji.kumar@wipro.com>
+ * Author: Saji Kumar.V.R <saji.kumar@wipro.com>
*
- * CHANGES:
- * 2005/01/01: add an hint to a possible solution when test fails
- * - Ricky Ng-Adam <rngadam@yahoo.com>
+ * 2005/01/01: add an hint to a possible solution when test fails
+ * Ricky Ng-Adam <rngadam@yahoo.com>
+ *
+ * Copyright (c) Linux Test Project, 2003-2023
*/
+
+/*\
+ * [Description]
+ *
+ * Test capset() with with LINUX_CAPABILITY_VERSION_{1,2,3}.
+ */
+
#include <sys/types.h>
#include <unistd.h>
#include "tst_test.h"
diff --git a/testcases/kernel/syscalls/capset/capset02.c b/testcases/kernel/syscalls/capset/capset02.c
index 5173be09b..989f3e4ce 100644
--- a/testcases/kernel/syscalls/capset/capset02.c
+++ b/testcases/kernel/syscalls/capset/capset02.c
@@ -2,21 +2,27 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* Author: Saji Kumar.V.R <saji.kumar@wipro.com>
- *
+ * Copyright (c) Linux Test Project, 2003-2023
+ */
+
+/*\
+ * [Description]
* Tests basic error handling of the capset syscall.
- * 1) capset() fails with errno set to EFAULT if an invalid address
+ *
+ * 1. capset() fails with errno set to EFAULT if an invalid address
* is given for header.
- * 2) capset() fails with errno set to EFAULT if an invalid address
+ * 2. capset() fails with errno set to EFAULT if an invalid address
* is given for data.
- * 3) capset() fails with errno set to EINVAL if an invalid value
+ * 3. capset() fails with errno set to EINVAL if an invalid value
* is given for header->version.
- * 4) capset() fails with errno set to EPERM if the new_Effective is
+ * 4. capset() fails with errno set to EPERM if the new_Effective is
* not a subset of the new_Permitted.
- * 5) capset() fails with errno set to EPERM if the new_Permitted is
+ * 5. capset() fails with errno set to EPERM if the new_Permitted is
* not a subset of the old_Permitted.
- * 6) capset() fails with errno set ot EPERM if the new_Inheritable is
+ * 6. capset() fails with errno set ot EPERM if the new_Inheritable is
* not a subset of the old_Inheritable and bounding set.
*/
+
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
diff --git a/testcases/kernel/syscalls/capset/capset03.c b/testcases/kernel/syscalls/capset/capset03.c
index 074ab1f50..2b83e6ce9 100644
--- a/testcases/kernel/syscalls/capset/capset03.c
+++ b/testcases/kernel/syscalls/capset/capset03.c
@@ -1,11 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
- * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
+ * Copyright (c) Linux Test Project, 2020-2023
+ * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
+ */
+
+/*\
+ * [Description]
*
* capset() fails with errno set or EPERM if the new_Inheritable is
* not a subset of old_Inheritable and old_Permitted without CAP_SETPCAP.
*/
+
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
diff --git a/testcases/kernel/syscalls/capset/capset04.c b/testcases/kernel/syscalls/capset/capset04.c
index f929be555..13477a4a9 100644
--- a/testcases/kernel/syscalls/capset/capset04.c
+++ b/testcases/kernel/syscalls/capset/capset04.c
@@ -1,12 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2020-2023
* Author: Saji Kumar.V.R <saji.kumar@wipro.com>
+ */
+
+/*\
+ * [Description]
*
- * Tests whether we can use capset() to modify the capabilities of a thread
+ * Test whether capset() can be used to modify the capabilities of a thread
* other than itself. Now, most linux distributions with kernel supporting
* VFS capabilities, this should be never permitted.
*/
+
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
diff --git a/testcases/kernel/syscalls/chdir/chdir01.c b/testcases/kernel/syscalls/chdir/chdir01.c
index e4080e3f4..d50a8f50c 100644
--- a/testcases/kernel/syscalls/chdir/chdir01.c
+++ b/testcases/kernel/syscalls/chdir/chdir01.c
@@ -31,18 +31,27 @@ static char *workdir;
static int skip_symlinks, skip_blocked;
static struct passwd *ltpuser;
+static char *file_name;
+static char *blocked_name;
+static char *dir_name;
+static char *cwd_name;
+static char *parent_name;
+static char *root_name;
+static char *missing_name;
+static char *link_name;
+
static struct test_case {
- const char *name;
+ char **name;
int root_ret, root_err, nobody_ret, nobody_err;
} testcase_list[] = {
- {FILE_NAME, -1, ENOTDIR, -1, ENOTDIR},
- {BLOCKED_NAME, 0, 0, -1, EACCES},
- {DIR_NAME, 0, 0, 0, 0},
- {".", 0, 0, 0, 0},
- {"..", 0, 0, 0, 0},
- {"/", 0, 0, 0, 0},
- {"missing", -1, ENOENT, -1, ENOENT},
- {LINK_NAME1, -1, ELOOP, -1, ELOOP},
+ {&file_name, -1, ENOTDIR, -1, ENOTDIR},
+ {&blocked_name, 0, 0, -1, EACCES},
+ {&dir_name, 0, 0, 0, 0},
+ {&cwd_name, 0, 0, 0, 0},
+ {&parent_name, 0, 0, 0, 0},
+ {&root_name, 0, 0, 0, 0},
+ {&missing_name, -1, ENOENT, -1, ENOENT},
+ {&link_name, -1, ELOOP, -1, ELOOP},
};
static void setup(void)
@@ -53,8 +62,6 @@ static void setup(void)
umask(0);
- SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, NULL);
-
cwd = SAFE_GETCWD(NULL, 0);
workdir = SAFE_MALLOC(strlen(cwd) + strlen(MNTPOINT) + 2);
sprintf(workdir, "%s/%s", cwd, MNTPOINT);
@@ -109,7 +116,7 @@ static void run(unsigned int n)
{
struct test_case *tc = testcase_list + n;
- tst_res(TINFO, "Testing '%s'", tc->name);
+ tst_res(TINFO, "Testing '%s'", *tc->name);
if (tc->root_err == ELOOP && skip_symlinks) {
tst_res(TCONF, "Skipping symlink loop test, not supported");
@@ -119,8 +126,8 @@ static void run(unsigned int n)
/* Reset current directory to mountpoint */
SAFE_CHDIR(workdir);
- TEST(chdir(tc->name));
- check_result("root", tc->name, tc->root_ret, tc->root_err);
+ TEST(chdir(*tc->name));
+ check_result("root", *tc->name, tc->root_ret, tc->root_err);
if (tc->nobody_err == EACCES && skip_blocked) {
tst_res(TCONF, "Skipping unprivileged permission test, "
@@ -130,25 +137,35 @@ static void run(unsigned int n)
SAFE_CHDIR(workdir);
SAFE_SETEUID(ltpuser->pw_uid);
- TEST(chdir(tc->name));
+ TEST(chdir(*tc->name));
SAFE_SETEUID(0);
- check_result(TESTUSER, tc->name, tc->nobody_ret, tc->nobody_err);
+ check_result(TESTUSER, *tc->name, tc->nobody_ret, tc->nobody_err);
}
static void cleanup(void)
{
SAFE_CHDIR("..");
- tst_umount(workdir);
free(workdir);
}
static struct tst_test test = {
.needs_root = 1,
- .format_device = 1,
+ .mount_device = 1,
.mntpoint = MNTPOINT,
.all_filesystems = 1,
.test = run,
.tcnt = ARRAY_SIZE(testcase_list),
.setup = setup,
- .cleanup = cleanup
+ .cleanup = cleanup,
+ .bufs = (struct tst_buffers []) {
+ {&file_name, .str = FILE_NAME},
+ {&blocked_name, .str = BLOCKED_NAME},
+ {&dir_name, .str = DIR_NAME},
+ {&cwd_name, .str = "."},
+ {&parent_name, .str = ".."},
+ {&root_name, .str = "/"},
+ {&missing_name, .str = "does_not_exist"},
+ {&link_name, .str = LINK_NAME1},
+ {}
+ }
};
diff --git a/testcases/kernel/syscalls/chmod/chmod01.c b/testcases/kernel/syscalls/chmod/chmod01.c
index 9f5ec4c67..b3b828ac3 100644
--- a/testcases/kernel/syscalls/chmod/chmod01.c
+++ b/testcases/kernel/syscalls/chmod/chmod01.c
@@ -19,13 +19,16 @@
static int modes[] = {0, 07, 070, 0700, 0777, 02777, 04777, 06777};
+static char *test_dir;
+static char *test_file;
+
static struct variant {
- char *name;
+ char **name;
unsigned int mode_mask;
char *desc;
} variants[] = {
- {TESTFILE, S_IFREG, "verify permissions of file"},
- {TESTDIR, S_IFDIR, "verify permissions of directory"},
+ {&test_file, S_IFREG, "verify permissions of file"},
+ {&test_dir, S_IFDIR, "verify permissions of directory"},
};
static void verify_chmod(unsigned int n)
@@ -34,21 +37,21 @@ static void verify_chmod(unsigned int n)
int mode = modes[n];
struct variant *tc = &variants[tst_variant];
- TST_EXP_PASS(chmod(tc->name, mode), "chmod(%s, %04o)",
- tc->name, mode);
+ TST_EXP_PASS(chmod(*tc->name, mode), "chmod(%s, %04o)",
+ *tc->name, mode);
if (!TST_PASS)
return;
- SAFE_STAT(tc->name, &stat_buf);
+ SAFE_STAT(*tc->name, &stat_buf);
stat_buf.st_mode &= ~tc->mode_mask;
if (stat_buf.st_mode == (unsigned int)mode) {
tst_res(TPASS, "stat(%s) mode=%04o",
- tc->name, stat_buf.st_mode);
+ *tc->name, stat_buf.st_mode);
} else {
tst_res(TFAIL, "stat(%s) mode=%04o",
- tc->name, stat_buf.st_mode);
+ *tc->name, stat_buf.st_mode);
}
}
@@ -57,9 +60,9 @@ static void setup(void)
tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
if (tst_variant)
- SAFE_MKDIR(variants[tst_variant].name, MODE);
+ SAFE_MKDIR(*variants[tst_variant].name, MODE);
else
- SAFE_TOUCH(variants[tst_variant].name, MODE, NULL);
+ SAFE_TOUCH(*variants[tst_variant].name, MODE, NULL);
}
static struct tst_test test = {
@@ -68,4 +71,9 @@ static struct tst_test test = {
.tcnt = ARRAY_SIZE(modes),
.test = verify_chmod,
.needs_tmpdir = 1,
+ .bufs = (struct tst_buffers []) {
+ {&test_file, .str = TESTFILE},
+ {&test_dir, .str = TESTDIR},
+ {}
+ }
};
diff --git a/testcases/kernel/syscalls/chown/chown02.c b/testcases/kernel/syscalls/chown/chown02.c
index 7c96832a4..467185831 100644
--- a/testcases/kernel/syscalls/chown/chown02.c
+++ b/testcases/kernel/syscalls/chown/chown02.c
@@ -9,6 +9,7 @@
* [Description]
*
* Verify that chown(2) invoked by super-user:
+ *
* - clears setuid and setgid bits set on an executable file
* - preserves setgid bit set on a non-group-executable file
*/
diff --git a/testcases/kernel/syscalls/chroot/chroot03.c b/testcases/kernel/syscalls/chroot/chroot03.c
index ba8c1e9ac..87faec316 100644
--- a/testcases/kernel/syscalls/chroot/chroot03.c
+++ b/testcases/kernel/syscalls/chroot/chroot03.c
@@ -25,41 +25,42 @@
#include <stdio.h>
#include "tst_test.h"
-static char fname[255];
-static char nonexistent_dir[100] = "testdir";
-static char bad_dir[] = "abcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyz";
-static char symbolic_dir[] = "sym_dir1";
+#define FILE_NAME "test_file"
+#define LOOP_DIR "sym_dir1"
+#define NONEXISTENT_DIR "does_not_exist"
+
+static char *longname_dir;
+static char *file_name;
+static char *nonexistent_dir;
+static char *bad_ptr;
+static char *loop_dir;
static struct tcase {
- char *dir;
+ char **dir;
int error;
char *desc;
} tcases[] = {
- {bad_dir, ENAMETOOLONG, "chroot(longer than VFS_MAXNAMELEN)"},
- {fname, ENOTDIR, "chroot(not a directory)"},
- {nonexistent_dir, ENOENT, "chroot(does not exists)"},
- {(char *)-1, EFAULT, "chroot(an invalid address)"},
- {symbolic_dir, ELOOP, "chroot(symlink loop)"}
+ {&longname_dir, ENAMETOOLONG, "chroot(longer than VFS_MAXNAMELEN)"},
+ {&file_name, ENOTDIR, "chroot(not a directory)"},
+ {&nonexistent_dir, ENOENT, "chroot(does not exists)"},
+ {&bad_ptr, EFAULT, "chroot(an invalid address)"},
+ {&loop_dir, ELOOP, "chroot(symlink loop)"}
};
static void verify_chroot(unsigned int n)
{
struct tcase *tc = &tcases[n];
- TST_EXP_FAIL(chroot(tc->dir), tc->error, "%s", tc->desc);
+ TST_EXP_FAIL(chroot(*tc->dir), tc->error, "%s", tc->desc);
}
static void setup(void)
{
- unsigned int i;
-
- (void)sprintf(fname, "tfile_%d", getpid());
- SAFE_TOUCH(fname, 0666, NULL);
+ SAFE_TOUCH(FILE_NAME, 0666, NULL);
+ bad_ptr = tst_get_bad_addr(NULL);
- for (i = 0; i < ARRAY_SIZE(tcases); i++) {
- if (tcases[i].error == EFAULT)
- tcases[3].dir = tst_get_bad_addr(NULL);
- }
+ memset(longname_dir, 'a', PATH_MAX + 1);
+ longname_dir[PATH_MAX+1] = 0;
SAFE_SYMLINK("sym_dir1/", "sym_dir2");
SAFE_SYMLINK("sym_dir2/", "sym_dir1");
@@ -70,4 +71,11 @@ static struct tst_test test = {
.tcnt = ARRAY_SIZE(tcases),
.test = verify_chroot,
.needs_tmpdir = 1,
+ .bufs = (struct tst_buffers []) {
+ {&file_name, .str = FILE_NAME},
+ {&nonexistent_dir, .str = NONEXISTENT_DIR},
+ {&loop_dir, .str = LOOP_DIR},
+ {&longname_dir, .size = PATH_MAX+2},
+ {}
+ }
};
diff --git a/testcases/kernel/syscalls/clone/clone04.c b/testcases/kernel/syscalls/clone/clone04.c
index 7af4fedd3..74347e2b4 100644
--- a/testcases/kernel/syscalls/clone/clone04.c
+++ b/testcases/kernel/syscalls/clone/clone04.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* Copyright (c) 2012 Wanlong Gao <gaowanlong@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2003-2023
*/
/*\
@@ -44,4 +45,8 @@ static void verify_clone(unsigned int nr)
static struct tst_test test = {
.tcnt = ARRAY_SIZE(tcases),
.test = verify_clone,
+ .tags = (const struct tst_tag[]) {
+ {"musl-git", "fa4a8abd06a4"},
+ {}
+ },
};
diff --git a/testcases/kernel/syscalls/clone3/.gitignore b/testcases/kernel/syscalls/clone3/.gitignore
index 604cb903e..10369954b 100644
--- a/testcases/kernel/syscalls/clone3/.gitignore
+++ b/testcases/kernel/syscalls/clone3/.gitignore
@@ -1,2 +1,3 @@
clone301
clone302
+clone303
diff --git a/testcases/kernel/syscalls/clone3/clone302.c b/testcases/kernel/syscalls/clone3/clone302.c
index b1b4ccebb..48b831554 100644
--- a/testcases/kernel/syscalls/clone3/clone302.c
+++ b/testcases/kernel/syscalls/clone3/clone302.c
@@ -12,6 +12,7 @@
#define _GNU_SOURCE
#include <stdlib.h>
+#include <assert.h>
#include "tst_test.h"
#include "lapi/sched.h"
@@ -34,7 +35,7 @@ static struct tcase {
} tcases[] = {
{"invalid args", &invalid_args, sizeof(*valid_args), 0, NULL, SIGCHLD, 0, 0, 0, EFAULT},
{"zero size", &valid_args, 0, 0, NULL, SIGCHLD, 0, 0, 0, EINVAL},
- {"short size", &valid_args, sizeof(*valid_args) - 1, 0, NULL, SIGCHLD, 0, 0, 0, EINVAL},
+ {"short size", &valid_args, sizeof(struct clone_args_minimal) - 1, 0, NULL, SIGCHLD, 0, 0, 0, EINVAL},
{"extra size", &valid_args, sizeof(*valid_args) + 1, 0, NULL, SIGCHLD, 0, 0, 0, EFAULT},
{"sighand-no-VM", &valid_args, sizeof(*valid_args), CLONE_SIGHAND, NULL, SIGCHLD, 0, 0, 0, EINVAL},
{"thread-no-sighand", &valid_args, sizeof(*valid_args), CLONE_THREAD, NULL, SIGCHLD, 0, 0, 0, EINVAL},
@@ -59,6 +60,8 @@ static void setup(void)
{
clone3_supported_by_kernel();
+ TST_EXP_EQ_SZ(sizeof(struct clone_args_minimal), 64);
+
void *p = tst_get_bad_addr(NULL);
invalid_args = p;
diff --git a/testcases/kernel/syscalls/clone3/clone303.c b/testcases/kernel/syscalls/clone3/clone303.c
new file mode 100644
index 000000000..04c41942a
--- /dev/null
+++ b/testcases/kernel/syscalls/clone3/clone303.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 SUSE LLC <wegao@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test case check clone3 CLONE_INTO_CGROUP flag
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#include "tst_test.h"
+#include "lapi/sched.h"
+#include "lapi/pidfd.h"
+
+#define BUF_LEN 20
+
+static struct tst_cg_group *cg_child_test_simple;
+static int fd;
+static struct tst_clone_args *args;
+
+static pid_t clone_into_cgroup(int cgroup_fd)
+{
+
+ args->flags = CLONE_INTO_CGROUP;
+ args->exit_signal = SIGCHLD;
+ args->cgroup = cgroup_fd;
+
+ return tst_clone(args);
+}
+
+static void run(void)
+{
+ pid_t pid;
+
+ pid = clone_into_cgroup(fd);
+
+ if (!pid) {
+ TST_CHECKPOINT_WAIT(0);
+ return;
+ }
+
+ char buf[BUF_LEN];
+
+ SAFE_CG_READ(cg_child_test_simple, "cgroup.procs", buf, BUF_LEN);
+
+ if (atoi(buf) == pid)
+ tst_res(TPASS, "clone3 case pass!");
+ else
+ tst_brk(TFAIL | TTERRNO, "clone3() failed !");
+
+ TST_CHECKPOINT_WAKE(0);
+
+ SAFE_WAITPID(pid, NULL, 0);
+
+}
+
+static void setup(void)
+{
+ clone3_supported_by_kernel();
+
+ cg_child_test_simple = tst_cg_group_mk(tst_cg, "cg_test_simple");
+
+ fd = tst_cg_group_unified_dir_fd(cg_child_test_simple);
+
+ if (fd < 0)
+ tst_brk(TBROK, "get dir fd failed!");
+}
+
+static void cleanup(void)
+{
+ cg_child_test_simple = tst_cg_group_rm(cg_child_test_simple);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .forks_child = 1,
+ .needs_cgroup_ctrls = (const char *const []){ "base", NULL },
+ .needs_cgroup_ver = TST_CG_V2,
+ .needs_checkpoints = 1,
+ .min_kver = "5.7",
+ .bufs = (struct tst_buffers []) {
+ {&args, .size = sizeof(*args)},
+ {},
+ }
+};
diff --git a/testcases/kernel/syscalls/delete_module/delete_module01.c b/testcases/kernel/syscalls/delete_module/delete_module01.c
index 476551233..90d8b5289 100644
--- a/testcases/kernel/syscalls/delete_module/delete_module01.c
+++ b/testcases/kernel/syscalls/delete_module/delete_module01.c
@@ -2,38 +2,39 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* Copyright (c) 2018 Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2002-2023
+ * Author: Madhu T L <madhu.tarikere@wipro.com>
*/
-/*
- * AUTHOR: Madhu T L <madhu.tarikere@wipro.com>
+/*\
+ * [Description]
+ *
+ * Basic test for delete_module(2).
*
- * DESCRIPTION:
- * Basic tests for delete_module(2)
- * 1) insmod dummy_del_mod.ko
- * 2) call delete_module(2) to remove dummy_del_mod.ko
+ * Install dummy_del_mod.ko and delete it with delete_module(2).
*/
-#include <errno.h>
#include "tst_test.h"
#include "tst_module.h"
#include "lapi/syscalls.h"
#define MODULE_NAME "dummy_del_mod"
-#define MODULE_NAME_KO "dummy_del_mod.ko"
+#define MODULE_NAME_KO MODULE_NAME ".ko"
static int module_loaded;
static void do_delete_module(void)
{
- if (module_loaded == 0) {
+ if (!module_loaded) {
tst_module_load(MODULE_NAME_KO, NULL);
module_loaded = 1;
}
TEST(tst_syscall(__NR_delete_module, MODULE_NAME, 0));
if (TST_RET == -1) {
- tst_res(TFAIL | TTERRNO, "delete_module() failed to "
- "remove module entry for %s ", MODULE_NAME);
+ tst_res(TFAIL | TTERRNO,
+ "delete_module() failed to remove module entry for %s",
+ MODULE_NAME);
return;
}
@@ -43,14 +44,15 @@ static void do_delete_module(void)
static void cleanup(void)
{
- if (module_loaded == 1)
+ if (module_loaded)
tst_module_unload(MODULE_NAME_KO);
}
static struct tst_test test = {
.needs_root = 1,
- /* lockdown requires signed modules */
+ /* lockdown and SecureBoot requires signed modules */
.skip_in_lockdown = 1,
+ .skip_in_secureboot = 1,
.cleanup = cleanup,
.test_all = do_delete_module,
};
diff --git a/testcases/kernel/syscalls/delete_module/delete_module03.c b/testcases/kernel/syscalls/delete_module/delete_module03.c
index 863d36188..7e92fc2af 100644
--- a/testcases/kernel/syscalls/delete_module/delete_module03.c
+++ b/testcases/kernel/syscalls/delete_module/delete_module03.c
@@ -72,8 +72,9 @@ static void cleanup(void)
static struct tst_test test = {
.needs_root = 1,
- /* lockdown requires signed modules */
+ /* lockdown and SecureBoot requires signed modules */
.skip_in_lockdown = 1,
+ .skip_in_secureboot = 1,
.setup = setup,
.cleanup = cleanup,
.test_all = do_delete_module,
diff --git a/testcases/kernel/syscalls/dup/dup01.c b/testcases/kernel/syscalls/dup/dup01.c
index 74e24cc02..f5cd058e8 100644
--- a/testcases/kernel/syscalls/dup/dup01.c
+++ b/testcases/kernel/syscalls/dup/dup01.c
@@ -7,27 +7,32 @@
*
*/
+/*\
+ * [Description]
+ *
+ * Verify that dup(2) syscall executes successfully and allocates
+ * a new file descriptor which refers to the same open file as oldfd.
+ */
+
#include "tst_test.h"
static int fd;
+static struct stat buf1, buf2;
static void verify_dup(void)
{
- TEST(dup(fd));
-
- if (TST_RET < -1) {
- tst_res(TFAIL, "Invalid dup() return value %ld", TST_RET);
- } else if (TST_RET == -1) {
- tst_res(TFAIL | TTERRNO, "dup(%d) Failed", fd);
- } else {
- tst_res(TPASS, "dup(%d) returned %ld", fd, TST_RET);
- SAFE_CLOSE(TST_RET);
- }
+ TST_EXP_FD(dup(fd));
+
+ SAFE_FSTAT(TST_RET, &buf2);
+ TST_EXP_EQ_LU(buf1.st_ino, buf2.st_ino);
+
+ SAFE_CLOSE(TST_RET);
}
static void setup(void)
{
fd = SAFE_OPEN("dupfile", O_RDWR | O_CREAT, 0700);
+ SAFE_FSTAT(fd, &buf1);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/dup/dup02.c b/testcases/kernel/syscalls/dup/dup02.c
index 528bcdbc1..5391738a4 100644
--- a/testcases/kernel/syscalls/dup/dup02.c
+++ b/testcases/kernel/syscalls/dup/dup02.c
@@ -2,24 +2,21 @@
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2020 SUSE LLC
- *
* 03/30/1992 AUTHOR: Richard Logan CO-PILOT: William Roske
- *
*/
+
/*\
* [Description]
- * Negative test for dup(2) with bad fds.
*
- * [Algorithm]
- * Call dup(2) with invalid argument and make sure it returns -1 with errno set
- * to EBADF.
+ * Verify that dup(2) syscall fails with errno EBADF when called with
+ * invalid value for oldfd argument.
*/
#include "tst_test.h"
static struct tcase {
int fd;
- int expected_errno;
+ int exp_err;
} tcases[] = {
{-1, EBADF},
{1500, EBADF},
@@ -29,27 +26,10 @@ static void run(unsigned int n)
{
struct tcase *tc = &tcases[n];
- TEST(dup(tc->fd));
-
- if (TST_RET < -1) {
- tst_res(TFAIL | TTERRNO, "Invalid dup() return value %ld",
- TST_RET);
- return;
- }
-
- if (TST_RET == -1) {
- if (tc->expected_errno == TST_ERR) {
- tst_res(TPASS | TTERRNO, "dup(%d) failed as expected",
- tc->fd);
- } else {
- tst_res(TFAIL | TTERRNO, "dup(%d) failed unexpectedly",
- tc->fd);
- }
- return;
- }
+ TST_EXP_FAIL2(dup(tc->fd), tc->exp_err, "dup(%d)", tc->fd);
- tst_res(TFAIL, "dup(%d) succeeded unexpectedly", tc->fd);
- SAFE_CLOSE(TST_RET);
+ if (TST_RET != -1)
+ SAFE_CLOSE(TST_RET);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/dup/dup03.c b/testcases/kernel/syscalls/dup/dup03.c
index 0e99813f4..d59e61f2b 100644
--- a/testcases/kernel/syscalls/dup/dup03.c
+++ b/testcases/kernel/syscalls/dup/dup03.c
@@ -6,48 +6,30 @@
*/
/*\
* [Description]
- * Negative test for dup(2) (too many fds).
*
- * [Algorithm]
- * Open the maximum allowed number of file descriptors and then try to call
- * dup() once more and verify it fails with EMFILE.
+ * Verify that dup(2) syscall fails with errno EMFILE when the per-process
+ * limit on the number of open file descriptors has been reached.
*/
#include <stdlib.h>
#include "tst_test.h"
-int *fd;
-int nfds;
+static int *fd;
+static int nfds;
static void run(void)
{
- TEST(dup(fd[0]));
+ TST_EXP_FAIL2(dup(fd[0]), EMFILE, "dup(%d)", fd[0]);
- if (TST_RET < -1) {
- tst_res(TFAIL, "Invalid dup() return value %ld", TST_RET);
- return;
- }
-
- if (TST_RET == -1) {
- if (TST_ERR == EMFILE)
- tst_res(TPASS | TTERRNO, "dup() failed as expected");
- else
- tst_res(TFAIL | TTERRNO, "dup() failed unexpectedly");
- return;
- }
-
- tst_res(TFAIL, "dup() succeeded unexpectedly");
- SAFE_CLOSE(TST_RET);
+ if (TST_RET != -1)
+ SAFE_CLOSE(TST_RET);
}
static void setup(void)
{
long maxfds;
- maxfds = sysconf(_SC_OPEN_MAX);
- if (maxfds == -1)
- tst_brk(TBROK, "sysconf(_SC_OPEN_MAX) failed");
-
+ maxfds = SAFE_SYSCONF(_SC_OPEN_MAX);
fd = SAFE_MALLOC(maxfds * sizeof(int));
fd[0] = SAFE_OPEN("dupfile", O_RDWR | O_CREAT, 0700);
diff --git a/testcases/kernel/syscalls/dup/dup04.c b/testcases/kernel/syscalls/dup/dup04.c
index 8d45f7a9c..053fb40c2 100644
--- a/testcases/kernel/syscalls/dup/dup04.c
+++ b/testcases/kernel/syscalls/dup/dup04.c
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
* 06/1994 AUTHOR: Richard Logan CO-PILOT: William Roske
+ * Copyright (c) 2023 SUSE LLC
*/
/*\
- * [DESCRIPTION]
+ * [Description]
*
* Basic test for dup(2) of a system pipe descriptor.
*/
@@ -17,38 +17,18 @@
#include "tst_test.h"
-int fd[2];
+static int fd[2];
static void run(void)
{
- TEST(dup(fd[0]));
-
- if (TST_RET == -1)
- tst_res(TFAIL | TTERRNO,
- "dup of read side of pipe failed");
- else {
- tst_res(TPASS,
- "dup(%d) read side of syspipe returned %ld",
- fd[0], TST_RET);
-
- SAFE_CLOSE(TST_RET);
- }
-
- TEST(dup(fd[1]));
-
- if (TST_RET == -1) {
- tst_res(TFAIL | TTERRNO,
- "dup of write side of pipe failed");
- } else {
- tst_res(TPASS,
- "dup(%d) write side of syspipe returned %ld",
- fd[1], TST_RET);
-
- SAFE_CLOSE(TST_RET);
- }
+ TST_EXP_FD(dup(fd[0]), "dup(%d) read end of the pipe", fd[0]);
+ SAFE_CLOSE(TST_RET);
+
+ TST_EXP_FD(dup(fd[1]), "dup(%d) write end of the pipe", fd[1]);
+ SAFE_CLOSE(TST_RET);
}
-void setup(void)
+static void setup(void)
{
fd[0] = -1;
@@ -56,7 +36,7 @@ void setup(void)
}
static struct tst_test test = {
- .test_all = run,
- .setup = setup,
- .needs_tmpdir = 1,
+ .test_all = run,
+ .setup = setup,
+ .needs_tmpdir = 1,
};
diff --git a/testcases/kernel/syscalls/dup/dup05.c b/testcases/kernel/syscalls/dup/dup05.c
index 362f3e170..619b4861e 100644
--- a/testcases/kernel/syscalls/dup/dup05.c
+++ b/testcases/kernel/syscalls/dup/dup05.c
@@ -1,55 +1,43 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
* 06/1994 AUTHOR: Richard Logan CO-PILOT: William Roske
+ * Copyright (c) 2012-2023 SUSE LLC
*/
/*\
- * [DESCRIPTION]
+ * [Description]
*
- * Basic test for dup(2) of a named pipe descriptor
+ * Basic test for dup(2) of a named pipe descriptor.
*/
-#include <stdio.h>
+
#include "tst_test.h"
-char Fname[255];
-int fd;
+#define FNAME "dupfile"
+
+static int fd = -1;
static void run(void)
{
- TEST(dup(fd));
-
- if (TST_RET == -1) {
- tst_res(TFAIL | TTERRNO, "dup failed");
- } else {
- tst_res(TPASS, "dup returned %ld",
- TST_RET);
-
- SAFE_CLOSE(TST_RET);
- }
+ TST_EXP_FD(dup(fd), "dup(%d)", fd);
+ SAFE_CLOSE(TST_RET);
}
-void setup(void)
+static void setup(void)
{
- fd = -1;
-
- sprintf(Fname, "dupfile");
- SAFE_MKFIFO(Fname, 0777);
- if ((fd = open(Fname, O_RDWR, 0700)) == -1)
- tst_brk(TBROK, "open failed");
+ SAFE_MKFIFO(FNAME, 0777);
+ fd = SAFE_OPEN(FNAME, O_RDWR, 0700);
}
-void cleanup(void)
+static void cleanup(void)
{
if (fd != -1)
- if (close(fd) == -1)
- tst_res(TWARN | TERRNO, "close failed");
+ SAFE_CLOSE(fd);
}
static struct tst_test test = {
- .test_all = run,
- .setup = setup,
- .cleanup = cleanup,
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
.needs_tmpdir = 1,
};
diff --git a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl02.c b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl02.c
index fe16ad1cb..dcf74bf77 100644
--- a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl02.c
+++ b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl02.c
@@ -67,7 +67,7 @@ static void setup(void)
events[1].data.fd = fd[1];
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd[0], &events[0]))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static void cleanup(void)
@@ -85,7 +85,7 @@ static void cleanup(void)
static void verify_epoll_ctl(unsigned int n)
{
TST_EXP_FAIL(epoll_ctl(*tc[n].epfd, tc[n].opt, *tc[n].fd, tc[n].event),
- tc[n].exp_err, "epoll_clt(...) if %s", tc[n].desc);
+ tc[n].exp_err, "epoll_ctl(...) if %s", tc[n].desc);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl03.c b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl03.c
index c92b0b62e..f617295cc 100644
--- a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl03.c
+++ b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl03.c
@@ -55,7 +55,7 @@ static void setup(void)
events.data.fd = fds[0];
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &events))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl04.c b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl04.c
index 5173755f7..bc015c01b 100644
--- a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl04.c
+++ b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl04.c
@@ -36,7 +36,7 @@ static void setup(void)
events.data.fd = epfd;
if (epoll_ctl(new_epfd, EPOLL_CTL_ADD, epfd, &events))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
epfd = new_epfd;
}
@@ -59,7 +59,7 @@ static void verify_epoll_ctl(void)
events.data.fd = epfd;
TST_EXP_FAIL(epoll_ctl(new_epfd, EPOLL_CTL_ADD, epfd, &events), EINVAL,
- "epoll_clt(..., EPOLL_CTL_ADD, ...) with number of nesting is 5");
+ "epoll_ctl(..., EPOLL_CTL_ADD, ...) with number of nesting is 5");
SAFE_CLOSE(new_epfd);
}
diff --git a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl05.c b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl05.c
index d03009cf3..71e300daa 100644
--- a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl05.c
+++ b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl05.c
@@ -40,12 +40,12 @@ static void setup(void)
events.data.fd = epfd;
if (epoll_ctl(new_epfd, EPOLL_CTL_ADD, epfd, &events))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
events.data.fd = fd[0];
if (epoll_ctl(origin_epfd, EPOLL_CTL_DEL, fd[0], &events))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_DEL, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_DEL, ...)");
}
static void cleanup(void)
@@ -61,7 +61,7 @@ static void verify_epoll_ctl(void)
{
events.data.fd = epfd;
TST_EXP_FAIL(epoll_ctl(origin_epfd, EPOLL_CTL_ADD, epfd, &events),
- ELOOP, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ ELOOP, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c
index f4a55e008..928d57803 100644
--- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c
+++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c
@@ -102,7 +102,7 @@ static void setup(void)
e.events = EPOLLIN;
if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c
index 7914f1c50..2ae32519f 100644
--- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c
+++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c
@@ -42,7 +42,7 @@ static void setup(void)
e.events = EPOLLIN;
if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
SAFE_WRITE(SAFE_WRITE_ALL, sfd[1], "w", 1);
}
diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c
index 2ad1a6abc..aa08daa1b 100644
--- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c
+++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c
@@ -50,7 +50,7 @@ static void setup(void)
e.events = EPOLLIN;
if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c
index 54b9be975..4be33488d 100644
--- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c
+++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c
@@ -38,7 +38,7 @@ static void setup(void)
e.events = EPOLLIN;
if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
SAFE_WRITE(SAFE_WRITE_ALL, sfd[1], "w", 1);
bad_addr = tst_get_bad_addr(NULL);
diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait05.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait05.c
index 4c4aeb77d..ed8f3e4f8 100644
--- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait05.c
+++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait05.c
@@ -46,7 +46,7 @@ static void setup(void)
e.events = EPOLLIN;
if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
SAFE_WRITE(SAFE_WRITE_ALL, sfd[1], "w", 1);
}
diff --git a/testcases/kernel/syscalls/epoll_wait/.gitignore b/testcases/kernel/syscalls/epoll_wait/.gitignore
index 222955dd2..66ac18ae2 100644
--- a/testcases/kernel/syscalls/epoll_wait/.gitignore
+++ b/testcases/kernel/syscalls/epoll_wait/.gitignore
@@ -2,3 +2,6 @@ epoll_wait01
epoll_wait02
epoll_wait03
epoll_wait04
+epoll_wait05
+epoll_wait06
+epoll_wait07
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
index d2c0b6ef4..93ada1cf3 100644
--- a/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait02.c
@@ -50,7 +50,7 @@ static void setup(void)
epevs[0].data.fd = fds[0];
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
index 4b21aba4c..d31e49864 100644
--- a/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
@@ -57,7 +57,7 @@ static void setup(void)
epevs[0].data.fd = fds[1];
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0]))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static void verify_epoll_wait(unsigned int n)
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait04.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait04.c
index dc62e9202..bd8baca22 100644
--- a/testcases/kernel/syscalls/epoll_wait/epoll_wait04.c
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait04.c
@@ -49,7 +49,7 @@ static void setup(void)
epevs[0].data.fd = fds[0];
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]))
- tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
+ tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
new file mode 100644
index 000000000..d06a024ff
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that epoll receives EPOLLRDHUP event when we hang a reading
+ * half-socket we are polling on.
+ */
+
+#include "tst_test.h"
+#include "tst_net.h"
+#include "tst_epoll.h"
+
+static int epfd;
+static int sockfd_client;
+static int sockfd_server;
+static in_port_t *sock_port;
+
+static void create_server(void)
+{
+ int sockfd_server;
+ socklen_t len;
+ struct sockaddr_in serv_addr;
+ struct sockaddr_in sin;
+
+ tst_init_sockaddr_inet_bin(&serv_addr, INADDR_ANY, 0);
+
+ sockfd_server = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
+ SAFE_BIND(sockfd_server, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
+ SAFE_LISTEN(sockfd_server, 10);
+
+ len = sizeof(sin);
+ memset(&sin, 0, sizeof(struct sockaddr_in));
+ SAFE_GETSOCKNAME(sockfd_server, (struct sockaddr *)&sin, &len);
+
+ *sock_port = ntohs(sin.sin_port);
+
+ tst_res(TINFO, "Listening on port %d", *sock_port);
+
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+ SAFE_CLOSE(sockfd_server);
+}
+
+static void run(void)
+{
+ struct sockaddr_in client_addr;
+ struct epoll_event evt_req;
+ struct epoll_event evt_rec;
+ int ret;
+
+ if (!SAFE_FORK()) {
+ create_server();
+ return;
+ }
+
+ TST_CHECKPOINT_WAIT(0);
+
+ tst_res(TINFO, "Connecting to port %d", *sock_port);
+
+ sockfd_client = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
+
+ tst_init_sockaddr_inet(&client_addr, "127.0.0.1", *sock_port);
+
+ SAFE_CONNECT(sockfd_client,
+ (struct sockaddr *)&client_addr,
+ sizeof(client_addr));
+
+ tst_res(TINFO, "Polling on socket");
+
+ epfd = SAFE_EPOLL_CREATE1(0);
+ evt_req.events = EPOLLRDHUP;
+ SAFE_EPOLL_CTL(epfd, EPOLL_CTL_ADD, sockfd_client, &evt_req);
+
+ tst_res(TINFO, "Hang socket");
+
+ TST_EXP_PASS_SILENT(shutdown(sockfd_client, SHUT_RD));
+ ret = SAFE_EPOLL_WAIT(epfd, &evt_rec, 1, 2000);
+ if (ret != 1) {
+ tst_res(TFAIL, "Wrong number of events reported %i", ret);
+ goto exit;
+ }
+
+ if (evt_rec.events & EPOLLRDHUP)
+ tst_res(TPASS, "Received EPOLLRDHUP");
+ else
+ tst_res(TFAIL, "EPOLLRDHUP has not been received");
+
+exit:
+ SAFE_CLOSE(epfd);
+ SAFE_CLOSE(sockfd_client);
+
+ TST_CHECKPOINT_WAKE(0);
+}
+
+static void setup(void)
+{
+ sock_port = SAFE_MMAP(NULL, sizeof(in_port_t), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+static void cleanup(void)
+{
+ if (sock_port)
+ SAFE_MUNMAP(sock_port, sizeof(in_port_t));
+
+ if (fcntl(sockfd_client, F_GETFD) > 0)
+ SAFE_CLOSE(sockfd_client);
+
+ if (fcntl(sockfd_server, F_GETFD) > 0)
+ SAFE_CLOSE(sockfd_server);
+
+ if (fcntl(epfd, F_GETFD) > 0)
+ SAFE_CLOSE(epfd);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait06.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait06.c
new file mode 100644
index 000000000..f35e0423a
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait06.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that edge triggering is correctly handled by epoll, for both EPOLLIN
+ * and EPOLLOUT.
+ *
+ * [Algorithm]
+ *
+ * - The file descriptors for non-blocking pipe are registered on an epoll
+ * instance.
+ * - A pipe writer writes data on the write side of the pipe.
+ * - A call to epoll_wait() is done that will return a EPOLLIN event.
+ * - The pipe reader reads half of data from rfd.
+ * - A call to epoll_wait() should hang because there's data left to read.
+ * - The pipe reader reads remaining data from rfd.
+ * - A call to epoll_wait() should return a EPOLLOUT event.
+ */
+
+#define _GNU_SOURCE
+
+#include <fcntl.h>
+#include "tst_test.h"
+#include "tst_epoll.h"
+
+static size_t write_size;
+static size_t read_size;
+static int fds[2];
+static int epfd;
+
+static void setup(void)
+{
+ write_size = getpagesize();
+ read_size = write_size / 2;
+
+ SAFE_PIPE2(fds, O_NONBLOCK);
+
+ /* EPOLLOUT will be raised when buffer became empty after becoming full */
+ SAFE_FCNTL(fds[1], F_SETPIPE_SZ, write_size);
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0)
+ SAFE_CLOSE(epfd);
+
+ if (fds[0] > 0)
+ SAFE_CLOSE(fds[0]);
+
+ if (fds[1] > 0)
+ SAFE_CLOSE(fds[1]);
+}
+
+static void run(void)
+{
+ char buff[write_size];
+ struct epoll_event evt_receive;
+
+ tst_res(TINFO, "Polling on channel with EPOLLET");
+
+ epfd = SAFE_EPOLL_CREATE1(0);
+
+ SAFE_EPOLL_CTL(epfd, EPOLL_CTL_ADD, fds[0], &((struct epoll_event) {
+ .events = EPOLLIN | EPOLLET,
+ .data.fd = fds[0],
+ }));
+ SAFE_EPOLL_CTL(epfd, EPOLL_CTL_ADD, fds[1], &((struct epoll_event) {
+ .events = EPOLLOUT | EPOLLET,
+ .data.fd = fds[1],
+ }));
+
+ tst_res(TINFO, "Write bytes on channel: %zu bytes", write_size);
+
+ memset(buff, 'a', write_size);
+ SAFE_WRITE(SAFE_WRITE_ANY, fds[1], buff, write_size);
+ TST_EXP_FAIL(write(fds[1], buff, write_size), EAGAIN, "write() failed");
+
+ TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 1, 0), 1);
+ TST_EXP_EQ_LI(evt_receive.data.fd, fds[0]);
+ TST_EXP_EQ_LI(evt_receive.events & EPOLLIN, EPOLLIN);
+
+ tst_res(TINFO, "Read half bytes from channel: %zu bytes", read_size);
+
+ memset(buff, 0, write_size);
+ SAFE_READ(1, fds[0], buff, read_size);
+
+ TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 1, 0), 0);
+
+ tst_res(TINFO, "Read remaining bytes from channel: %zu bytes", read_size);
+
+ SAFE_READ(1, fds[0], buff + read_size, read_size);
+ TST_EXP_FAIL(read(fds[0], buff, read_size), EAGAIN, "read() failed");
+
+ TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 1, 0), 1);
+ TST_EXP_EQ_LI(evt_receive.data.fd, fds[1]);
+ TST_EXP_EQ_LI(evt_receive.events & EPOLLOUT, EPOLLOUT);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait07.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait07.c
new file mode 100644
index 000000000..dfabd0d87
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait07.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that EPOLLONESHOT is correctly handled by epoll_wait.
+ * We open a channel, write in it two times and verify that EPOLLIN has been
+ * received only once.
+ */
+
+#include <poll.h>
+#include <sys/epoll.h>
+#include "tst_test.h"
+#include "tst_epoll.h"
+
+static int fds[2];
+static int epfd;
+
+static void cleanup(void)
+{
+ if (epfd > 0)
+ SAFE_CLOSE(epfd);
+
+ if (fds[0] > 0)
+ SAFE_CLOSE(fds[0]);
+
+ if (fds[1] > 0)
+ SAFE_CLOSE(fds[1]);
+}
+
+static void run(void)
+{
+ struct epoll_event evt_receive;
+ char buff = 'a';
+
+ SAFE_PIPE(fds);
+
+ tst_res(TINFO, "Polling on channel with EPOLLONESHOT");
+
+ epfd = SAFE_EPOLL_CREATE1(0);
+
+ SAFE_EPOLL_CTL(epfd, EPOLL_CTL_ADD, fds[0], &((struct epoll_event) {
+ .events = EPOLLIN | EPOLLONESHOT,
+ .data.fd = fds[0],
+ }));
+
+ tst_res(TINFO, "Write channel for the 1st time. EPOLLIN expected");
+
+ SAFE_WRITE(0, fds[1], &buff, 1);
+ TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 10, 0), 1);
+ TST_EXP_EQ_LI(evt_receive.events & EPOLLIN, EPOLLIN);
+ TST_EXP_EQ_LI(evt_receive.data.fd, fds[0]);
+
+ SAFE_READ(1, fds[0], &buff, 1);
+ TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 10, 0), 0);
+
+ tst_res(TINFO, "Write channel for the 2nd time. No events expected");
+
+ SAFE_WRITE(0, fds[1], &buff, 1);
+ TST_EXP_EQ_LI(SAFE_EPOLL_WAIT(epfd, &evt_receive, 10, 0), 0);
+
+ SAFE_CLOSE(epfd);
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(fds[1]);
+}
+
+static struct tst_test test = {
+ .cleanup = cleanup,
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/eventfd/.gitignore b/testcases/kernel/syscalls/eventfd/.gitignore
index db45c67cf..4f577370c 100644
--- a/testcases/kernel/syscalls/eventfd/.gitignore
+++ b/testcases/kernel/syscalls/eventfd/.gitignore
@@ -1 +1,6 @@
/eventfd01
+/eventfd02
+/eventfd03
+/eventfd04
+/eventfd05
+/eventfd06
diff --git a/testcases/kernel/syscalls/eventfd/eventfd01.c b/testcases/kernel/syscalls/eventfd/eventfd01.c
index 9b60434a2..b66d6a55c 100644
--- a/testcases/kernel/syscalls/eventfd/eventfd01.c
+++ b/testcases/kernel/syscalls/eventfd/eventfd01.c
@@ -1,738 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
- * Copyright (c) Linux Test Project, 2008-2022
- *
- * Based on testcases/kernel/syscalls/waitpid/waitpid01.c
- * Original copyright message:
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
+ * Copyright (c) Linux Test Project, 2008-2022
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * NAME
- * eventfd01.c
- *
- * DESCRIPTION
- * Test cases for eventfd syscall.
+/*\
+ * [Description]
*
- * USAGE: <for command-line>
- * eventfd01 [-c n] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- *
- * History
- * 07/2008 Vijay Kumar
- * Initial Version.
- *
- * Restrictions
- * None
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "test.h"
-#define CLEANUP cleanup
-#include "lapi/syscalls.h"
-
-TCID_DEFINE(eventfd01);
-int TST_TOTAL = 15;
-
-#ifdef HAVE_LIBAIO
-#include <libaio.h>
-
-static void setup(void);
-
-static int myeventfd(unsigned int initval, int flags)
-{
- /* eventfd2 uses FLAGS but eventfd doesn't take FLAGS. */
- return tst_syscall(__NR_eventfd, initval);
-}
-
-/*
- * clear_counter() - clears the counter by performing a dummy read
- * @fd: the eventfd
+ * Verify read operation for eventfd fail with:
*
- * RETURNS:
- * 0 on success, and -1 on failure
- */
-static int clear_counter(int fd)
-{
- uint64_t dummy;
- int ret;
-
- ret = read(fd, &dummy, sizeof(dummy));
- if (ret == -1) {
- if (errno != EAGAIN) {
- tst_resm(TINFO | TERRNO, "error clearing counter");
- return -1;
- }
- }
-
- return 0;
-}
-
-/*
- * set_counter() - sets the count to specified value
- * @fd: the eventfd
- * @val: the value to be set
- *
- * Clears the counter and sets the counter to @val.
- *
- * RETURNS:
- * 0 on success, -1 on failure
- */
-static int set_counter(int fd, uint64_t val)
-{
- int ret;
-
- ret = clear_counter(fd);
- if (ret == -1)
- return -1;
-
- ret = write(fd, &val, sizeof(val));
- if (ret == -1) {
- tst_resm(TINFO | TERRNO, "error setting counter value");
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Test whether the current value of the counter matches @required.
- */
-static void read_test(int fd, uint64_t required)
-{
- int ret;
- uint64_t val;
-
- ret = read(fd, &val, sizeof(val));
- if (ret == -1) {
- tst_resm(TBROK | TERRNO, "error reading eventfd");
- return;
- }
-
- if (val == required)
- tst_resm(TPASS, "counter value matches required");
- else
- tst_resm(TFAIL, "counter value mismatch: "
- "required: %" PRIu64 ", got: %" PRIu64, required, val);
-}
-
-/*
- * Test whether read returns with error EAGAIN when counter is at 0.
- */
-static void read_eagain_test(int fd)
-{
- int ret;
- uint64_t val;
-
- ret = clear_counter(fd);
- if (ret == -1) {
- tst_resm(TBROK, "error clearing counter");
- return;
- }
-
- ret = read(fd, &val, sizeof(val));
- if (ret == -1) {
- if (errno == EAGAIN)
- tst_resm(TPASS, "read failed with EAGAIN as expected");
- else
- tst_resm(TFAIL | TERRNO, "read failed (wanted EAGAIN)");
- } else
- tst_resm(TFAIL, "read returned with %d", ret);
-}
-
-/*
- * Test whether writing to counter works.
+ * - EAGAIN when counter is zero on non blocking fd
+ * - EINVAL when buffer size is less than 8 bytes
*/
-static void write_test(int fd)
-{
- int ret;
- uint64_t val;
-
- val = 12;
- ret = set_counter(fd, val);
- if (ret == -1) {
- tst_resm(TBROK, "error setting counter value to %" PRIu64, val);
- return;
- }
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include "tst_test.h"
- read_test(fd, val);
-}
+#define EVENT_COUNT 10
-/*
- * Test whether write returns with error EAGAIN when counter is at
- * (UINT64_MAX - 1).
- */
-static void write_eagain_test(int fd)
+static void run(void)
{
- int ret;
+ int fd;
uint64_t val;
-
- ret = set_counter(fd, UINT64_MAX - 1);
- if (ret == -1) {
- tst_resm(TBROK, "error setting counter value to UINT64_MAX-1");
- return;
- }
-
- val = 1;
- ret = write(fd, &val, sizeof(val));
- if (ret == -1) {
- if (errno == EAGAIN)
- tst_resm(TPASS, "write failed with EAGAIN as expected");
- else
- tst_resm(TFAIL, "write failed (wanted EAGAIN)");
- } else
- tst_resm(TFAIL, "write returned with %d", ret);
-}
-
-/*
- * Test whether read returns with error EINVAL, if buffer size is less
- * than 8 bytes.
- */
-static void read_einval_test(int fd)
-{
uint32_t invalid;
- int ret;
- ret = read(fd, &invalid, sizeof(invalid));
- if (ret == -1) {
- if (errno == EINVAL)
- tst_resm(TPASS, "read failed with EINVAL as expected");
- else
- tst_resm(TFAIL | TERRNO, "read failed (wanted EINVAL)");
- } else
- tst_resm(TFAIL, "read returned with %d", ret);
-}
+ fd = TST_EXP_FD(eventfd(EVENT_COUNT, EFD_NONBLOCK));
-/*
- * Test whether write returns with error EINVAL, if buffer size is
- * less than 8 bytes.
- */
-static void write_einval_test(int fd)
-{
- uint32_t invalid;
- int ret;
+ SAFE_READ(0, fd, &val, sizeof(val));
+ TST_EXP_EQ_LI(val, EVENT_COUNT);
- ret = write(fd, &invalid, sizeof(invalid));
- if (ret == -1) {
- if (errno == EINVAL)
- tst_resm(TPASS, "write failed with EINVAL as expected");
- else
- tst_resm(TFAIL | TERRNO,
- "write failed (wanted EINVAL)");
- } else
- tst_resm(TFAIL, "write returned with %d", ret);
-}
+ TST_EXP_FAIL(read(fd, &val, sizeof(val)), EAGAIN);
+ TST_EXP_FAIL(read(fd, &invalid, sizeof(invalid)), EINVAL);
-/*
- * Test wheter write returns with error EINVAL, when the written value
- * is 0xFFFFFFFFFFFFFFFF.
- */
-static void write_einval2_test(int fd)
-{
- int ret;
- uint64_t val;
-
- ret = clear_counter(fd);
- if (ret == -1) {
- tst_resm(TBROK, "error clearing counter");
- return;
- }
-
- val = 0xffffffffffffffffLL;
- ret = write(fd, &val, sizeof(val));
- if (ret == -1) {
- if (errno == EINVAL)
- tst_resm(TPASS, "write failed with EINVAL as expected");
- else
- tst_resm(TFAIL | TERRNO,
- "write failed (wanted EINVAL)");
- } else {
- tst_resm(TFAIL, "write returned with %d", ret);
- }
+ SAFE_CLOSE(fd);
}
-/*
- * Test whether readfd is set by select when counter value is
- * non-zero.
- */
-static void readfd_set_test(int fd)
-{
- int ret;
- fd_set readfds;
- struct timeval timeout = { 0, 0 };
- uint64_t non_zero = 10;
-
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
-
- ret = set_counter(fd, non_zero);
- if (ret == -1) {
- tst_resm(TBROK, "error setting counter value to %" PRIu64,
- non_zero);
- return;
- }
-
- ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
- if (ret == -1) {
- /* EINTR cannot occur, since we don't block. */
- tst_resm(TBROK | TERRNO, "select() failed");
- return;
- }
-
- if (FD_ISSET(fd, &readfds))
- tst_resm(TPASS, "fd is set in readfds");
- else
- tst_resm(TFAIL, "fd is not set in readfds");
-}
-
-/*
- * Test whether readfd is not set by select when counter value is
- * zero.
- */
-static void readfd_not_set_test(int fd)
-{
- int ret;
- fd_set readfds;
- struct timeval timeout = { 0, 0 };
-
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
-
- ret = clear_counter(fd);
- if (ret == -1) {
- tst_resm(TBROK, "error clearing counter");
- return;
- }
-
- ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
- if (ret == -1) {
- /* EINTR cannot occur, since we don't block. */
- tst_resm(TBROK | TERRNO, "select() failed");
- return;
- }
-
- if (!FD_ISSET(fd, &readfds))
- tst_resm(TPASS, "fd is not set in readfds");
- else
- tst_resm(TFAIL, "fd is set in readfds");
-}
-
-/*
- * Test whether writefd is set by select when counter value is not the
- * maximum counter value.
- */
-static void writefd_set_test(int fd)
-{
- int ret;
- fd_set writefds;
- struct timeval timeout = { 0, 0 };
- uint64_t non_max = 10;
-
- FD_ZERO(&writefds);
- FD_SET(fd, &writefds);
-
- ret = set_counter(fd, non_max);
- if (ret == -1) {
- tst_resm(TBROK, "error setting counter value to %" PRIu64,
- non_max);
- return;
- }
-
- ret = select(fd + 1, NULL, &writefds, NULL, &timeout);
- if (ret == -1) {
- /* EINTR cannot occur, since we don't block. */
- tst_resm(TBROK | TERRNO, "select: error getting fd status");
- return;
- }
-
- if (FD_ISSET(fd, &writefds))
- tst_resm(TPASS, "fd is set in writefds");
- else
- tst_resm(TFAIL, "fd is not set in writefds");
-}
-
-/*
- * Test whether writefd is not set by select when counter value is at
- * (UINT64_MAX - 1).
- */
-static void writefd_not_set_test(int fd)
-{
- int ret;
- fd_set writefds;
- struct timeval timeout = { 0, 0 };
-
- FD_ZERO(&writefds);
- FD_SET(fd, &writefds);
-
- ret = set_counter(fd, UINT64_MAX - 1);
- if (ret == -1) {
- tst_resm(TBROK, "error setting counter value to UINT64_MAX-1");
- return;
- }
-
- ret = select(fd + 1, NULL, &writefds, NULL, &timeout);
- if (ret == -1) {
- /* EINTR cannot occur, since we don't block. */
- tst_resm(TBROK | TERRNO, "select: error getting fd status");
- return;
- }
-
- if (!FD_ISSET(fd, &writefds))
- tst_resm(TPASS, "fd is not set in writefds");
- else
- tst_resm(TFAIL, "fd is set in writefds");
-}
-
-/*
- * Test whether counter update in child is reflected in the parent.
- */
-static void child_inherit_test(int fd)
-{
- uint64_t val;
- pid_t cpid;
- int ret;
- int status;
- uint64_t to_parent = 0xdeadbeef;
- uint64_t dummy;
-
- cpid = fork();
- if (cpid == -1)
- tst_resm(TBROK | TERRNO, "fork failed");
- else if (cpid != 0) {
- ret = wait(&status);
- if (ret == -1) {
- tst_resm(TBROK, "error getting child exit status");
- return;
- }
-
- if (WEXITSTATUS(status) == 1) {
- tst_resm(TBROK, "counter value write not "
- "successful in child");
- return;
- }
-
- ret = read(fd, &val, sizeof(val));
- if (ret == -1) {
- tst_resm(TBROK | TERRNO, "error reading eventfd");
- return;
- }
-
- if (val == to_parent)
- tst_resm(TPASS, "counter value write from "
- "child successful");
- else
- tst_resm(TFAIL, "counter value write in child "
- "failed");
- } else {
- /* Child */
- ret = read(fd, &dummy, sizeof(dummy));
- if (ret == -1 && errno != EAGAIN) {
- tst_resm(TWARN | TERRNO, "error clearing counter");
- exit(1);
- }
-
- ret = write(fd, &to_parent, sizeof(to_parent));
- if (ret == -1) {
- tst_resm(TWARN | TERRNO, "error writing eventfd");
- exit(1);
- }
-
- exit(0);
- }
-}
-
-#ifdef HAVE_IO_SET_EVENTFD
-/*
- * Test whether counter overflow is detected and handled correctly.
- *
- * It is not possible to directly overflow the counter using the
- * write() syscall. Overflows occur when the counter is incremented
- * from kernel space, in an irq context, when it is not possible to
- * block the calling thread of execution.
- *
- * The AIO subsystem internally uses eventfd mechanism for
- * notification of completion of read or write requests. In this test
- * we trigger a counter overflow, by setting the counter value to the
- * max possible value initially. When the AIO subsystem notifies
- * through the eventfd counter, the counter overflows.
- *
- * NOTE: If the the counter starts from an initial value of 0, it will
- * take decades for an overflow to occur. But since we set the initial
- * value to the max possible counter value, we are able to cause it to
- * overflow with a single increment.
- *
- * When the counter overflows, the following are tested
- * 1. Check whether POLLERR event occurs in poll() for the eventfd.
- * 2. Check whether readfd_set/writefd_set is set in select() for the
- eventfd.
- * 3. The counter value is UINT64_MAX.
- */
-static int trigger_eventfd_overflow(int evfd, int *fd, io_context_t * ctx)
-{
- int ret;
- struct iocb iocb;
- struct iocb *iocbap[1];
- struct io_event ioev;
- static char buf[4 * 1024];
-
- *ctx = 0;
- ret = io_setup(16, ctx);
- if (ret < 0) {
- errno = -ret;
- if (errno == ENOSYS) {
- tst_brkm(TCONF | TERRNO, cleanup,
- "io_setup(): AIO not supported by kernel");
- }
-
- tst_resm(TINFO | TERRNO, "io_setup error");
- return -1;
- }
-
- *fd = open("testfile", O_RDWR | O_CREAT, 0644);
- if (*fd == -1) {
- tst_resm(TINFO | TERRNO, "open(testfile) failed");
- goto err_io_destroy;
- }
-
- ret = set_counter(evfd, UINT64_MAX - 1);
- if (ret == -1) {
- tst_resm(TINFO, "error setting counter to UINT64_MAX-1");
- goto err_close_file;
- }
-
- io_prep_pwrite(&iocb, *fd, buf, sizeof(buf), 0);
- io_set_eventfd(&iocb, evfd);
-
- iocbap[0] = &iocb;
- ret = io_submit(*ctx, 1, iocbap);
- if (ret < 0) {
- errno = -ret;
- tst_resm(TINFO | TERRNO, "error submitting iocb");
- goto err_close_file;
- }
-
- ret = io_getevents(*ctx, 1, 1, &ioev, NULL);
- if (ret < 0) {
- errno = -ret;
- tst_resm(TINFO | TERRNO, "error waiting for event");
- goto err_close_file;
- }
-
- return 0;
-
-err_close_file:
- close(*fd);
-
-err_io_destroy:
- io_destroy(*ctx);
-
- return -1;
-}
-
-static void cleanup_overflow(int fd, io_context_t ctx)
-{
- close(fd);
- io_destroy(ctx);
-}
-
-static void overflow_select_test(int evfd)
-{
- struct timeval timeout = { 10, 0 };
- fd_set readfds;
- int fd;
- io_context_t ctx;
- int ret;
-
- ret = trigger_eventfd_overflow(evfd, &fd, &ctx);
- if (ret == -1) {
- tst_resm(TBROK, "error triggering eventfd overflow");
- return;
- }
-
- FD_ZERO(&readfds);
- FD_SET(evfd, &readfds);
- ret = select(evfd + 1, &readfds, NULL, NULL, &timeout);
- if (ret == -1)
- tst_resm(TBROK | TERRNO,
- "error getting evfd status with select");
- else {
- if (FD_ISSET(evfd, &readfds))
- tst_resm(TPASS, "read fd set as expected");
- else
- tst_resm(TFAIL, "read fd not set");
- }
- cleanup_overflow(fd, ctx);
-}
-
-static void overflow_poll_test(int evfd)
-{
- struct pollfd pollfd;
- int fd;
- io_context_t ctx;
- int ret;
-
- ret = trigger_eventfd_overflow(evfd, &fd, &ctx);
- if (ret == -1) {
- tst_resm(TBROK, "error triggering eventfd overflow");
- return;
- }
-
- pollfd.fd = evfd;
- pollfd.events = POLLIN;
- pollfd.revents = 0;
- ret = poll(&pollfd, 1, 10000);
- if (ret == -1)
- tst_resm(TBROK | TERRNO, "error getting evfd status with poll");
- else {
- if (pollfd.revents & POLLERR)
- tst_resm(TPASS, "POLLERR occurred as expected");
- else
- tst_resm(TFAIL, "POLLERR did not occur");
- }
- cleanup_overflow(fd, ctx);
-}
-
-static void overflow_read_test(int evfd)
-{
- uint64_t count;
- io_context_t ctx;
- int fd;
- int ret;
-
- ret = trigger_eventfd_overflow(evfd, &fd, &ctx);
- if (ret == -1) {
- tst_resm(TBROK, "error triggering eventfd overflow");
- return;
- }
-
- ret = read(evfd, &count, sizeof(count));
- if (ret == -1)
- tst_resm(TBROK | TERRNO, "error reading eventfd");
- else {
-
- if (count == UINT64_MAX)
- tst_resm(TPASS, "overflow occurred as expected");
- else
- tst_resm(TFAIL, "overflow did not occur");
- }
- cleanup_overflow(fd, ctx);
-}
-#else
-static void overflow_select_test(int evfd)
-{
- tst_resm(TCONF, "eventfd support is not available in AIO subsystem");
-}
-
-static void overflow_poll_test(int evfd)
-{
- tst_resm(TCONF, "eventfd support is not available in AIO subsystem");
-}
-
-static void overflow_read_test(int evfd)
-{
- tst_resm(TCONF, "eventfd support is not available in AIO subsystem");
-}
-#endif
-
-int main(int argc, char **argv)
-{
- int lc;
- int fd;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- int ret;
- uint64_t einit = 10;
-
- tst_count = 0;
-
- fd = myeventfd(einit, 0);
- if (fd == -1)
- tst_brkm(TBROK | TERRNO, CLEANUP,
- "error creating eventfd");
-
- ret = fcntl(fd, F_SETFL, O_NONBLOCK);
- if (ret == -1)
- tst_brkm(TBROK | TERRNO, CLEANUP,
- "error setting non-block mode");
-
- read_test(fd, einit);
- read_eagain_test(fd);
- write_test(fd);
- write_eagain_test(fd);
- read_einval_test(fd);
- write_einval_test(fd);
- write_einval2_test(fd);
- readfd_set_test(fd);
- readfd_not_set_test(fd);
- writefd_set_test(fd);
- writefd_not_set_test(fd);
- child_inherit_test(fd);
- overflow_select_test(fd);
- overflow_poll_test(fd);
- overflow_read_test(fd);
-
- close(fd);
- }
-
- cleanup();
-
- tst_exit();
-}
-
-static void setup(void)
-{
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- tst_tmpdir();
-
- TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
- tst_rmdir();
-}
-
-#else
-int main(void)
-{
- tst_brkm(TCONF, NULL, "test requires libaio and it's development packages");
-}
-#endif
+static struct tst_test test = {
+ .test_all = run,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_EVENTFD",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/eventfd/eventfd02.c b/testcases/kernel/syscalls/eventfd/eventfd02.c
new file mode 100644
index 000000000..f028961c7
--- /dev/null
+++ b/testcases/kernel/syscalls/eventfd/eventfd02.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
+ * Copyright (c) Linux Test Project, 2008-2022
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify write operation for eventfd fail with:
+ *
+ * - EAGAIN when counter is zero on non blocking fd
+ * - EINVAL when buffer size is less than 8 bytes, or if an attempt is made to
+ * write the value 0xffffffffffffffff
+ */
+
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include "tst_test.h"
+
+static void run(void)
+{
+ int fd;
+ uint64_t val = 12;
+ uint64_t buf;
+ uint32_t invalid;
+
+ fd = TST_EXP_FD(eventfd(0, EFD_NONBLOCK));
+
+ SAFE_WRITE(0, fd, &val, sizeof(val));
+ SAFE_READ(0, fd, &buf, sizeof(buf));
+ TST_EXP_EQ_LI(buf, val);
+
+ val = UINT64_MAX - 1;
+ SAFE_WRITE(0, fd, &val, sizeof(val));
+ TST_EXP_FAIL(write(fd, &val, sizeof(val)), EAGAIN);
+ TST_EXP_FAIL(write(fd, &invalid, sizeof(invalid)), EINVAL);
+
+ val = 0xffffffffffffffffLL;
+ TST_EXP_FAIL(write(fd, &val, sizeof(val)), EINVAL);
+
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_EVENTFD",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/eventfd/eventfd03.c b/testcases/kernel/syscalls/eventfd/eventfd03.c
new file mode 100644
index 000000000..452264cad
--- /dev/null
+++ b/testcases/kernel/syscalls/eventfd/eventfd03.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
+ * Copyright (c) Linux Test Project, 2008-2022
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test whether readfd is set by select() when eventfd() counter value is
+ * non-zero, then check if readfd is not set when eventfd() counter value is
+ * zero.
+ */
+
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include "tst_test.h"
+
+static void run(void)
+{
+ int fd;
+ uint64_t val;
+ fd_set readfds;
+ uint64_t non_zero = 10;
+ struct timeval timeout = { 0, 0 };
+
+ fd = TST_EXP_FD(eventfd(0, EFD_NONBLOCK));
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ SAFE_WRITE(0, fd, &non_zero, sizeof(non_zero));
+ TEST(select(fd + 1, &readfds, NULL, NULL, &timeout));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "select");
+
+ TST_EXP_EQ_LI(FD_ISSET(fd, &readfds), 1);
+
+ SAFE_READ(0, fd, &val, sizeof(val));
+ TEST(select(fd + 1, &readfds, NULL, NULL, &timeout));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "select");
+
+ TST_EXP_EQ_LI(FD_ISSET(fd, &readfds), 0);
+
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_EVENTFD",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/eventfd/eventfd04.c b/testcases/kernel/syscalls/eventfd/eventfd04.c
new file mode 100644
index 000000000..c7186ae64
--- /dev/null
+++ b/testcases/kernel/syscalls/eventfd/eventfd04.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
+ * Copyright (c) Linux Test Project, 2008-2022
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test whether writefd is set by select() when eventfd() counter value is
+ * not the maximum value, then check if writefd is not set when eventfd()
+ * counter value is maximum value.
+ */
+
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include "tst_test.h"
+
+static void run(void)
+{
+ int fd;
+ fd_set writefds;
+ uint64_t val;
+ uint64_t non_max = 10;
+ uint64_t max = UINT64_MAX - 1;
+ struct timeval timeout = { 0, 0 };
+
+ fd = TST_EXP_FD(eventfd(0, EFD_NONBLOCK));
+
+ FD_ZERO(&writefds);
+ FD_SET(fd, &writefds);
+
+ SAFE_WRITE(0, fd, &non_max, sizeof(non_max));
+ TEST(select(fd + 1, NULL, &writefds, NULL, &timeout));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "select");
+
+ TST_EXP_EQ_LI(FD_ISSET(fd, &writefds), 1);
+
+ SAFE_READ(0, fd, &val, sizeof(val));
+ SAFE_WRITE(0, fd, &max, sizeof(max));
+
+ TEST(select(fd + 1, NULL, &writefds, NULL, &timeout));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "select");
+
+ TST_EXP_EQ_LI(FD_ISSET(fd, &writefds), 0);
+
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_EVENTFD",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/eventfd/eventfd05.c b/testcases/kernel/syscalls/eventfd/eventfd05.c
new file mode 100644
index 000000000..6ea2c4138
--- /dev/null
+++ b/testcases/kernel/syscalls/eventfd/eventfd05.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
+ * Copyright (c) Linux Test Project, 2008-2022
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test whether eventfd() counter update in child is reflected in the parent.
+ */
+
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include "tst_test.h"
+
+static void run(void)
+{
+ int fd;
+ uint64_t val;
+ uint64_t to_parent = 0xdeadbeef;
+
+ fd = TST_EXP_FD(eventfd(0, EFD_NONBLOCK));
+
+ if (!SAFE_FORK()) {
+ SAFE_WRITE(0, fd, &to_parent, sizeof(to_parent));
+ exit(0);
+ }
+
+ tst_reap_children();
+
+ SAFE_READ(0, fd, &val, sizeof(val));
+ TST_EXP_EQ_LI(val, to_parent);
+
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_EVENTFD",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/eventfd/eventfd06.c b/testcases/kernel/syscalls/eventfd/eventfd06.c
new file mode 100644
index 000000000..7339dd471
--- /dev/null
+++ b/testcases/kernel/syscalls/eventfd/eventfd06.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org>
+ * Copyright (c) Linux Test Project, 2008-2022
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test whether counter overflow is detected and handled correctly.
+ *
+ * It is not possible to directly overflow the counter using the
+ * write() syscall. Overflows occur when the counter is incremented
+ * from kernel space, in an IRQ context, when it is not possible to
+ * block the calling thread of execution.
+ *
+ * The AIO subsystem internally uses eventfd mechanism for
+ * notification of completion of read or write requests. In this test
+ * we trigger a counter overflow, by setting the counter value to the
+ * max possible value initially. When the AIO subsystem notifies
+ * through the eventfd counter, the counter overflows.
+ *
+ * If the counter starts from an initial value of 0, it will
+ * take decades for an overflow to occur. But since we set the initial
+ * value to the max possible counter value, we are able to cause it to
+ * overflow with a single increment.
+ *
+ * When the counter overflows, the following is tested:
+ *
+ * - POLLERR event occurs in poll() for the eventfd
+ * - readfd_set/writefd_set is set in select() for the eventfd
+ * - the counter value is UINT64_MAX
+ */
+
+#include "tst_test.h"
+
+#ifdef HAVE_LIBAIO
+#ifdef HAVE_IO_SET_EVENTFD
+
+#include <poll.h>
+#include <libaio.h>
+#include <stdlib.h>
+#include <sys/eventfd.h>
+
+#define MAXEVENTS 16
+#define BUFSIZE 1024
+
+static int fd;
+static int evfd;
+static io_context_t ctx;
+
+static void async_write(void)
+{
+ struct iocb iocb;
+ struct iocb *iocbap[1];
+ struct io_event ioev;
+ static char buf[BUFSIZE];
+
+ memset(buf, 1, BUFSIZE);
+
+ io_prep_pwrite(&iocb, fd, buf, sizeof(buf), 0);
+ io_set_eventfd(&iocb, evfd);
+
+ iocbap[0] = &iocb;
+ TEST(io_submit(ctx, 1, iocbap));
+ if (TST_RET < 0)
+ tst_brk(TBROK, "io_submit() failed: %s", tst_strerrno(-TST_RET));
+
+ TEST(io_getevents(ctx, 1, 1, &ioev, NULL));
+ if (TST_RET < 0)
+ tst_brk(TBROK, "io_getevents() failed: %s", tst_strerrno(-TST_RET));
+}
+
+static void clear_counter(void)
+{
+ uint64_t val;
+ uint64_t max = UINT64_MAX - 1;
+
+ TEST(read(evfd, &val, sizeof(val)));
+ if (TST_RET == -1 && TST_ERR != EAGAIN)
+ tst_brk(TBROK | TERRNO, "read");
+
+ SAFE_WRITE(0, evfd, &max, sizeof(max));
+}
+
+static void test_select(void)
+{
+ fd_set readfds;
+ uint64_t count;
+ struct timeval timeout = { 10, 0 };
+
+ clear_counter();
+ async_write();
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ tst_res(TINFO, "Checking if select() detects counter overflow");
+
+ TEST(select(fd + 1, NULL, &readfds, NULL, &timeout));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "select");
+
+ TST_EXP_EQ_LI(FD_ISSET(fd, &readfds), 1);
+
+ SAFE_READ(0, evfd, &count, sizeof(count));
+ TST_EXP_EQ_LI(count, UINT64_MAX);
+}
+
+static void test_poll(void)
+{
+ uint64_t count;
+ struct pollfd pollfd;
+
+ clear_counter();
+ async_write();
+
+ pollfd.fd = evfd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
+
+ tst_res(TINFO, "Checking if poll() detects counter overflow");
+
+ TEST(poll(&pollfd, 1, 10000));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "poll");
+
+ TST_EXP_EQ_LI(pollfd.revents & POLLERR, POLLERR);
+
+ SAFE_READ(0, evfd, &count, sizeof(count));
+ TST_EXP_EQ_LI(count, UINT64_MAX);
+}
+
+static void setup(void)
+{
+ TEST(io_setup(MAXEVENTS, &ctx));
+ if (TST_RET < 0)
+ tst_brk(TBROK, "io_setup() failed: %s", tst_strerrno(-TST_RET));
+
+ fd = SAFE_OPEN("testfile", O_RDWR | O_CREAT, 0644);
+ evfd = TST_EXP_FD(eventfd(0, EFD_NONBLOCK));
+}
+
+static void cleanup(void)
+{
+ SAFE_CLOSE(evfd);
+ io_destroy(ctx);
+}
+
+static void run(void)
+{
+ test_select();
+ test_poll();
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_EVENTFD",
+ NULL
+ },
+};
+
+#else /* HAVE_IO_SET_EVENTFD */
+TST_TEST_TCONF("eventfd support is not available in AIO subsystem");
+#endif
+#else /* HAVE_LIBAIO */
+TST_TEST_TCONF("libaio is not available");
+#endif
diff --git a/testcases/kernel/syscalls/eventfd2/eventfd2.h b/testcases/kernel/syscalls/eventfd2/eventfd2.h
new file mode 100644
index 000000000..5350820b8
--- /dev/null
+++ b/testcases/kernel/syscalls/eventfd2/eventfd2.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+
+static inline int eventfd2(unsigned int count, unsigned int flags)
+{
+ int ret;
+
+ ret = tst_syscall(__NR_eventfd2, count, flags);
+ if (ret == -1)
+ tst_brk(TBROK | TERRNO, "eventfd2");
+
+ return ret;
+}
diff --git a/testcases/kernel/syscalls/eventfd2/eventfd2_01.c b/testcases/kernel/syscalls/eventfd2/eventfd2_01.c
index 85ad86d42..3a80379a3 100644
--- a/testcases/kernel/syscalls/eventfd2/eventfd2_01.c
+++ b/testcases/kernel/syscalls/eventfd2/eventfd2_01.c
@@ -1,119 +1,37 @@
-/******************************************************************************/
-/* */
-/* Copyright (c) Ulrich Drepper <drepper@redhat.com> */
-/* Copyright (c) International Business Machines Corp., 2009 */
-/* */
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/******************************************************************************/
-/* */
-/* File: eventfd2_01.c */
-/* */
-/* Description: This Program tests the new system call introduced in 2.6.27. */
-/* Ulrich´s comment as in: */
-/* http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b087498eb5605673b0f260a7620d91818cd72304 */
-/* says: */
-/* This patch adds the new eventfd2 syscall. It extends the old eventfd */
-/* syscall by one parameter which is meant to hold a flag value. In this */
-/* patch the only flag support is EFD_CLOEXEC which causes the close-on-exec */
-/* flag for the returned file descriptor to be set. A new name EFD_CLOEXEC is */
-/* introduced which in this implementation must have the same value as */
-/* O_CLOEXEC. The following test must be adjusted for architectures other than*/
-/* x86 and x86-64 and in case the syscall numbers changed. */
-/* */
-/* Usage: <for command-line> */
-/* eventfd2_01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
-/* where, -c n : Run n copies concurrently. */
-/* -e : Turn on errno logging. */
-/* -i n : Execute test n times. */
-/* -I x : Execute test for x seconds. */
-/* -P x : Pause for x seconds between iterations. */
-/* -t : Turn on syscall timing. */
-/* */
-/* Total Tests: 1 */
-/* */
-/* Test Name: eventfd2_01 */
-/* */
-/* Author: Ulrich Drepper <drepper@redhat.com> */
-/* */
-/* History: Created - Jan 08 2009 - Ulrich Drepper <drepper@redhat.com> */
-/* Ported to LTP */
-/* - Jan 08 2009 - Subrata <subrata@linux.vnet.ibm.com> */
-/******************************************************************************/
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <errno.h>
-
-#include "test.h"
-#include "lapi/fcntl.h"
-#include "lapi/syscalls.h"
-
-#define EFD_CLOEXEC O_CLOEXEC
-
-char *TCID = "eventfd2_01";
-int testno;
-int TST_TOTAL = 1;
-
-void cleanup(void)
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Ulrich Drepper <drepper@redhat.com>
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies that eventfd2 correctly set FD_CLOEXEC flag on file when
+ * EFD_CLOEXEC flag is used.
+ */
+
+#include <fcntl.h>
+#include <sys/eventfd.h>
+#include "tst_test.h"
+#include "eventfd2.h"
+
+static void run(void)
{
- tst_rmdir();
-}
+ int fd, flags;
-void setup(void)
-{
- TEST_PAUSE;
- tst_tmpdir();
-}
+ fd = eventfd2(1, 0);
+ flags = SAFE_FCNTL(fd, F_GETFD);
+ TST_EXP_EXPR(!(flags & FD_CLOEXEC), "FD_CLOEXEC is not set");
+ SAFE_CLOSE(fd);
-int main(int argc, char *argv[])
-{
- int fd, coe;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
-
- fd = tst_syscall(__NR_eventfd2, 1, 0);
- if (fd == -1) {
- tst_brkm(TFAIL, cleanup, "eventfd2(0) failed");
- }
- coe = fcntl(fd, F_GETFD);
- if (coe == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if (coe & FD_CLOEXEC) {
- tst_brkm(TFAIL, cleanup, "eventfd2(0) set close-on-exec flag");
- }
- close(fd);
-
- fd = tst_syscall(__NR_eventfd2, 1, EFD_CLOEXEC);
- if (fd == -1) {
- tst_brkm(TFAIL, cleanup, "eventfd2(EFD_CLOEXEC) failed");
- }
- coe = fcntl(fd, F_GETFD);
- if (coe == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if ((coe & FD_CLOEXEC) == 0) {
- tst_brkm(TFAIL, cleanup,
- "eventfd2(EFD_CLOEXEC) does not set close-on-exec flag");
- }
- close(fd);
- tst_resm(TPASS, "eventfd2(EFD_CLOEXEC) Passed");
- cleanup();
- tst_exit();
+ fd = eventfd2(1, EFD_CLOEXEC);
+ flags = SAFE_FCNTL(fd, F_GETFD);
+ TST_EXP_EXPR((flags & FD_CLOEXEC), "FD_CLOEXEC is set");
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/eventfd2/eventfd2_02.c b/testcases/kernel/syscalls/eventfd2/eventfd2_02.c
index 5f3b6ee67..430cdb33c 100644
--- a/testcases/kernel/syscalls/eventfd2/eventfd2_02.c
+++ b/testcases/kernel/syscalls/eventfd2/eventfd2_02.c
@@ -1,118 +1,37 @@
-/******************************************************************************/
-/* */
-/* Copyright (c) Ulrich Drepper <drepper@redhat.com> */
-/* Copyright (c) International Business Machines Corp., 2009 */
-/* */
-/* 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, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/******************************************************************************/
-/* */
-/* File: eventfd2_02.c */
-/* */
-/* Description: This Program tests the new system call introduced in 2.6.27. */
-/* Ulrich´s comment as in: */
-/* http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e7d476dfdf0bcfed478a207aecfdc84f81efecaf */
-/* which says: */
-/* This patch adds support for the EFD_NONBLOCK flag to eventfd2. The */
-/* additional changes needed are minimal. The following test must be adjusted */
-/* or architectures other than x86 and x86-64 and in case the syscall numbers */
-/* changed. */
-/* */
-/* Usage: <for command-line> */
-/* eventfd2_02 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
-/* where, -c n : Run n copies concurrently. */
-/* -e : Turn on errno logging. */
-/* -i n : Execute test n times. */
-/* -I x : Execute test for x seconds. */
-/* -P x : Pause for x seconds between iterations. */
-/* -t : Turn on syscall timing. */
-/* */
-/* Total Tests: 1 */
-/* */
-/* Test Name: eventfd2_02 */
-/* */
-/* Author: Ulrich Drepper <drepper@redhat.com> */
-/* */
-/* History: Created - Jan 13 2009 - Ulrich Drepper <drepper@redhat.com> */
-/* Ported to LTP */
-/* - Jan 13 2009 - Subrata <subrata@linux.vnet.ibm.com> */
-/******************************************************************************/
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <errno.h>
-
-#include "test.h"
-#include "lapi/fcntl.h"
-#include "lapi/syscalls.h"
-
-#define EFD_NONBLOCK O_NONBLOCK
-
-char *TCID = "eventfd2_02";
-int testno;
-int TST_TOTAL = 1;
-
-void cleanup(void)
-{
- tst_rmdir();
-}
-
-void setup(void)
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Ulrich Drepper <drepper@redhat.com>
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies that eventfd2 correctly set O_NONBLOCK flag on file when
+ * EFD_NONBLOCK flag is used.
+ */
+
+#include <fcntl.h>
+#include <sys/eventfd.h>
+#include "tst_test.h"
+#include "eventfd2.h"
+
+static void run(void)
{
- TEST_PAUSE;
- tst_tmpdir();
-}
-
-int main(int argc, char *argv[])
-{
- int fd, fl;
-
- tst_parse_opts(argc, argv, NULL, NULL);
+ int fd, flags;
- setup();
+ fd = eventfd2(1, 0);
+ flags = SAFE_FCNTL(fd, F_GETFL);
+ TST_EXP_EXPR(!(flags & O_NONBLOCK), "O_NONBLOCK is not set");
+ SAFE_CLOSE(fd);
- tst_count = 0;
- fd = tst_syscall(__NR_eventfd2, 1, 0);
- if (fd == -1) {
- tst_brkm(TFAIL, cleanup, "eventfd2(0) failed");
- }
- fl = fcntl(fd, F_GETFL);
- if (fl == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if (fl & O_NONBLOCK) {
- tst_brkm(TFAIL, cleanup, "eventfd2(0) sets non-blocking mode");
- }
- close(fd);
-
- fd = tst_syscall(__NR_eventfd2, 1, EFD_NONBLOCK);
- if (fd == -1) {
- tst_brkm(TFAIL, cleanup, "eventfd2(EFD_NONBLOCK) failed");
- }
- fl = fcntl(fd, F_GETFL);
- if (fl == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if ((fl & O_NONBLOCK) == 0) {
- tst_brkm(TFAIL, cleanup,
- "eventfd2(EFD_NONBLOCK) didn't set non-blocking mode");
- }
- close(fd);
- tst_resm(TPASS, "eventfd2(EFD_NONBLOCK) PASSED");
-
- cleanup();
- tst_exit();
+ fd = eventfd2(1, EFD_NONBLOCK);
+ flags = SAFE_FCNTL(fd, F_GETFL);
+ TST_EXP_EXPR((flags & O_NONBLOCK), "O_NONBLOCK is set");
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/eventfd2/eventfd2_03.c b/testcases/kernel/syscalls/eventfd2/eventfd2_03.c
index 909004edb..e1949fd32 100644
--- a/testcases/kernel/syscalls/eventfd2/eventfd2_03.c
+++ b/testcases/kernel/syscalls/eventfd2/eventfd2_03.c
@@ -1,139 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * eventfd-sem by Davide Libenzi (Simple test for eventfd sempahore)
- * Copyright (C) 2009 Davide Libenzi
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Davide Libenzi <davidel@xmailserver.org>
- * Reference: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=bcd0b235bf3808dec5115c381cd55568f63b85f0
- * Reference: http://www.xmailserver.org/eventfd-sem.c
- * eventfd: testing improved support for semaphore-like behavior in linux-2.6.30
+ * Copyright (c) Ulrich Drepper <drepper@redhat.com>
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
*
+ * This test verifies that eventfd2 semaphore-like support is properly working.
*/
-#include <sys/types.h>
-#include <sys/syscall.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
#include <fcntl.h>
#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include "test.h"
-#include "lapi/syscalls.h"
-
-char *TCID = "eventfd2_03";
-int TST_TOTAL = 1;
-
-#ifndef EFD_SEMLIKE
-#define EFD_SEMLIKE (1 << 0)
-#endif
-
-/* Dummy function as syscall from linux_syscall_numbers.h uses cleanup(). */
-void cleanup(void)
-{
-}
-
-static int eventfd2(int count, int flags)
-{
- return tst_syscall(__NR_eventfd2, count, flags);
-}
+#include <sys/eventfd.h>
+#include "tst_test.h"
+#include "eventfd2.h"
static void xsem_wait(int fd)
{
u_int64_t cntr;
- if (read(fd, &cntr, sizeof(cntr)) != sizeof(cntr)) {
- perror("reading eventfd");
- exit(1);
- }
- fprintf(stdout, "[%u] wait completed on %d: count=%" PRIu64 "\n",
- getpid(), fd, cntr);
+ SAFE_READ(0, fd, &cntr, sizeof(cntr));
}
static void xsem_post(int fd, int count)
{
u_int64_t cntr = count;
- if (write(fd, &cntr, sizeof(cntr)) != sizeof(cntr)) {
- perror("writing eventfd");
- exit(1);
- }
+ SAFE_WRITE(0, fd, &cntr, sizeof(cntr));
}
static void sem_player(int fd1, int fd2)
{
- fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
- xsem_post(fd1, 1);
+ pid_t pid = getpid();
- fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
- xsem_wait(fd2);
-
- fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
+ tst_res(TINFO, "[%u] posting 1 on fd=%d", pid, fd1);
xsem_post(fd1, 1);
- fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
+ tst_res(TINFO, "[%u] waiting on fd=%d", pid, fd2);
xsem_wait(fd2);
- fprintf(stdout, "[%u] posting 5 on %d\n", getpid(), fd1);
+ tst_res(TINFO, "[%u] posting 5 on fd=%d", pid, fd1);
xsem_post(fd1, 5);
- fprintf(stdout, "[%u] waiting 5 times on %d\n", getpid(), fd2);
+ tst_res(TINFO, "[%u] waiting 5 times on fd=%d", pid, fd2);
xsem_wait(fd2);
xsem_wait(fd2);
xsem_wait(fd2);
xsem_wait(fd2);
xsem_wait(fd2);
-}
-static void usage(char const *prg)
-{
- fprintf(stderr, "use: %s [-h]\n", prg);
+ tst_res(TPASS, "[%u] received all events", pid);
}
-int main(int argc, char **argv)
+static void run(void)
{
- int c, fd1, fd2, status;
pid_t cpid_poster, cpid_waiter;
+ int fd1, fd2;
- while ((c = getopt(argc, argv, "h")) != -1) {
- switch (c) {
- default:
- usage(argv[0]);
- return 1;
- }
- }
- if ((fd1 = eventfd2(0, EFD_SEMLIKE)) == -1 ||
- (fd2 = eventfd2(0, EFD_SEMLIKE)) == -1) {
- perror("eventfd2");
- return 1;
- }
- if ((cpid_poster = fork()) == 0) {
+ fd1 = eventfd2(0, EFD_SEMAPHORE);
+ fd2 = eventfd2(0, EFD_SEMAPHORE);
+
+ cpid_poster = SAFE_FORK();
+ if (!cpid_poster) {
sem_player(fd1, fd2);
exit(0);
}
- if ((cpid_waiter = fork()) == 0) {
+
+ cpid_waiter = SAFE_FORK();
+ if (!cpid_waiter) {
sem_player(fd2, fd1);
exit(0);
}
- waitpid(cpid_poster, &status, 0);
- waitpid(cpid_waiter, &status, 0);
-
- tst_exit();
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/syscalls/execve/execve01.c b/testcases/kernel/syscalls/execve/execve01.c
index 2b12c7666..53f0475e3 100644
--- a/testcases/kernel/syscalls/execve/execve01.c
+++ b/testcases/kernel/syscalls/execve/execve01.c
@@ -34,7 +34,7 @@ static void verify_execve(void)
pid = SAFE_FORK();
if (pid == 0) {
execve(path, args, envp);
- tst_brk(TFAIL | TERRNO, "Failed to execute execl01_child");
+ tst_brk(TFAIL | TERRNO, "Failed to execute execve01_child");
}
}
diff --git a/testcases/kernel/syscalls/execve/execve06.c b/testcases/kernel/syscalls/execve/execve06.c
index afbfcfa9e..a00089265 100644
--- a/testcases/kernel/syscalls/execve/execve06.c
+++ b/testcases/kernel/syscalls/execve/execve06.c
@@ -35,7 +35,7 @@ static void verify_execve(void)
pid = SAFE_FORK();
if (pid == 0) {
execve(path, argv, envp);
- tst_brk(TFAIL | TERRNO, "Failed to execute execl01_child");
+ tst_brk(TFAIL | TERRNO, "Failed to execute execve06_child");
}
}
diff --git a/testcases/kernel/syscalls/faccessat/.gitignore b/testcases/kernel/syscalls/faccessat/.gitignore
index 9551ab97e..276caca45 100644
--- a/testcases/kernel/syscalls/faccessat/.gitignore
+++ b/testcases/kernel/syscalls/faccessat/.gitignore
@@ -1 +1,2 @@
/faccessat01
+/faccessat02
diff --git a/testcases/kernel/syscalls/faccessat/faccessat01.c b/testcases/kernel/syscalls/faccessat/faccessat01.c
index d11e8cf12..557d7eb4c 100644
--- a/testcases/kernel/syscalls/faccessat/faccessat01.c
+++ b/testcases/kernel/syscalls/faccessat/faccessat01.c
@@ -1,151 +1,88 @@
-/******************************************************************************
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: Yi Yang <yyangcdl@cn.ibm.com>
+ */
+
+/*\
+ * [Description]
*
- * Copyright (c) International Business Machines Corp., 2006
+ * Check the basic functionality of the faccessat() system call.
*
- * 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.
+ * - faccessat() passes if dir_fd is file descriptor to the directory
+ * where the file is located and pathname is relative path of the file.
*
- * 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.
+ * - faccessat() passes if dir_fd is a bad file descriptor and pathname is
+ * absolute path of the file.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * NAME
- * faccessat01.c
- *
- * DESCRIPTION
- * This test case will verify basic function of faccessat
- * added by kernel 2.6.16 or up.
- *
- * Author
- * Yi Yang <yyangcdl@cn.ibm.com>
- *
- * History
- * 08/28/2006 Created first by Yi Yang <yyangcdl@cn.ibm.com>
- *
- *****************************************************************************/
-
-#define _GNU_SOURCE
+ * - faccessat() passes if dir_fd is AT_FDCWD and pathname is interpreted
+ * relative to the current working directory of the calling process.
+ */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include "test.h"
-#include "safe_macros.h"
-#include "lapi/syscalls.h"
-
-#define TEST_CASES 6
-#ifndef AT_FDCWD
-#define AT_FDCWD -100
-#endif
-void setup();
-void cleanup();
-
-char *TCID = "faccessat01";
-int TST_TOTAL = TEST_CASES;
-static char pathname[256];
-static char testfile[256];
-static char testfile2[256];
-static char testfile3[256];
-static int fds[TEST_CASES];
-static char *filenames[TEST_CASES];
-static int expected_errno[TEST_CASES] = { 0, 0, ENOTDIR, EBADF, 0, 0 };
-
-int myfaccessat(int dirfd, const char *filename, int mode)
+#include <stdio.h>
+#include "tst_test.h"
+
+#define TESTDIR "faccessatdir"
+#define TESTFILE "faccessatfile"
+#define FILEPATH "faccessatdir/faccessatfile"
+
+static int dir_fd, file_fd;
+static int atcwd_fd = AT_FDCWD;
+static char *abs_path;
+static char *test_file;
+static char *file_path;
+
+static struct tcase {
+ int *fd;
+ char **filename;
+ int exp_errno;
+} tcases[] = {
+ {&dir_fd, &test_file, 0},
+ {&dir_fd, &abs_path, 0},
+ {&atcwd_fd, &file_path, 0},
+};
+
+static void verify_faccessat(unsigned int i)
{
- return tst_syscall(__NR_faccessat, dirfd, filename, mode);
-}
-
-int main(int ac, char **av)
-{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
+ struct tcase *tc = &tcases[i];
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- /*
- * Call faccessat
- */
- for (i = 0; i < TST_TOTAL; i++) {
- TEST(myfaccessat(fds[i], filenames[i], R_OK));
-
- /* check return code */
- if (TEST_ERRNO == expected_errno[i]) {
- tst_resm(TPASS,
- "faccessat() returned the expected errno %d: %s",
- TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_resm(TFAIL,
- "faccessdat() Failed, errno=%d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- }
- }
- }
-
- cleanup();
- tst_exit();
+ TST_EXP_PASS(faccessat(*tc->fd, *tc->filename, R_OK, 0),
+ "faccessat(%d, %s, R_OK, 0)",
+ *tc->fd, *tc->filename);
}
-void setup(void)
+static void setup(void)
{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- tst_tmpdir();
-
- char *abs_path = tst_get_tmpdir();
- int p = getpid();
-
- /* Initialize test dir and file names */
- sprintf(pathname, "faccessattestdir%d", p);
- sprintf(testfile, "faccessattestfile%d.txt", p);
- sprintf(testfile2, "%s/faccessattestfile%d.txt", abs_path, p);
- sprintf(testfile3, "faccessattestdir%d/faccessattestfile%d.txt", p, p);
-
- free(abs_path);
+ char *tmpdir_path = tst_get_tmpdir();
- SAFE_MKDIR(cleanup, pathname, 0700);
+ abs_path = tst_aprintf("%s/%s", tmpdir_path, FILEPATH);
+ free(tmpdir_path);
- fds[0] = SAFE_OPEN(cleanup, pathname, O_DIRECTORY);
- fds[1] = fds[4] = fds[0];
-
- SAFE_FILE_PRINTF(cleanup, testfile, "%s", testfile);
- SAFE_FILE_PRINTF(cleanup, testfile2, "%s", testfile2);
-
- fds[2] = SAFE_OPEN(cleanup, testfile3, O_CREAT | O_RDWR, 0600);
-
- fds[3] = 100;
- fds[5] = AT_FDCWD;
-
- filenames[0] = filenames[2] = filenames[3] = filenames[4] = testfile;
- filenames[1] = testfile2;
- filenames[5] = testfile3;
-
- TEST_PAUSE;
+ SAFE_MKDIR(TESTDIR, 0700);
+ dir_fd = SAFE_OPEN(TESTDIR, O_DIRECTORY);
+ file_fd = SAFE_OPEN(FILEPATH, O_CREAT | O_RDWR, 0600);
}
-void cleanup(void)
+static void cleanup(void)
{
- if (fds[0] > 0)
- close(fds[0]);
- if (fds[2] > 0)
- close(fds[2]);
+ if (dir_fd > -1)
+ SAFE_CLOSE(dir_fd);
- tst_rmdir();
+ if (file_fd > -1)
+ SAFE_CLOSE(file_fd);
}
+
+static struct tst_test test = {
+ .test = verify_faccessat,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .bufs = (struct tst_buffers []) {
+ {&test_file, .str = TESTFILE},
+ {&file_path, .str = FILEPATH},
+ {},
+ },
+ .needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/faccessat/faccessat02.c b/testcases/kernel/syscalls/faccessat/faccessat02.c
new file mode 100644
index 000000000..1add695c1
--- /dev/null
+++ b/testcases/kernel/syscalls/faccessat/faccessat02.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: Yi Yang <yyangcdl@cn.ibm.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * - faccessat() fails with ENOTDIR if dir_fd is file descriptor to the file
+ * and pathname is relative path of the file.
+ *
+ * - faccessat() fails with EBADF if dir_fd is invalid.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "tst_test.h"
+
+#define TESTDIR "faccessatdir"
+#define TESTFILE "faccessatfile"
+#define FILEPATH "faccessatdir/faccessatfile"
+
+static int dir_fd, file_fd;
+static int bad_fd = -1;
+
+static struct tcase {
+ int *fd;
+ int exp_errno;
+} tcases[] = {
+ {&file_fd, ENOTDIR},
+ {&bad_fd, EBADF},
+};
+
+static void verify_faccessat(unsigned int i)
+{
+ struct tcase *tc = &tcases[i];
+
+ TST_EXP_FAIL(faccessat(*tc->fd, TESTFILE, R_OK, 0),
+ tc->exp_errno, "faccessat(%d, TESTFILE, R_OK, 0)",
+ *tc->fd);
+}
+
+static void setup(void)
+{
+ SAFE_MKDIR(TESTDIR, 0700);
+ dir_fd = SAFE_OPEN(TESTDIR, O_DIRECTORY);
+ file_fd = SAFE_OPEN(FILEPATH, O_CREAT | O_RDWR, 0600);
+}
+
+static void cleanup(void)
+{
+ if (dir_fd > -1)
+ SAFE_CLOSE(dir_fd);
+
+ if (file_fd > -1)
+ SAFE_CLOSE(file_fd);
+}
+
+static struct tst_test test = {
+ .test = verify_faccessat,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/faccessat2/.gitignore b/testcases/kernel/syscalls/faccessat2/.gitignore
new file mode 100644
index 000000000..f58f045f4
--- /dev/null
+++ b/testcases/kernel/syscalls/faccessat2/.gitignore
@@ -0,0 +1,2 @@
+/faccessat201
+/faccessat202
diff --git a/testcases/kernel/syscalls/faccessat2/Makefile b/testcases/kernel/syscalls/faccessat2/Makefile
new file mode 100644
index 000000000..aaac6b703
--- /dev/null
+++ b/testcases/kernel/syscalls/faccessat2/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+# Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/faccessat2/faccessat201.c b/testcases/kernel/syscalls/faccessat2/faccessat201.c
new file mode 100644
index 000000000..012091752
--- /dev/null
+++ b/testcases/kernel/syscalls/faccessat2/faccessat201.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Check the basic functionality of faccessat2().
+ *
+ * Minimum Linux version required is v5.8.
+ */
+
+#include <stdlib.h>
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/faccessat.h"
+
+#define TESTDIR "faccessat2dir"
+#define TESTFILE "faccessat2file"
+#define RELPATH "faccessat2dir/faccessat2file"
+#define TESTSYMLINK "faccessat2symlink"
+
+static int dir_fd, bad_fd = -1;
+static int atcwd_fd = AT_FDCWD;
+static char *testfile;
+static char *abs_path;
+static char *rel_path;
+static char *sym_path;
+
+static struct tcase {
+ int *fd;
+ char **filename;
+ int flags;
+} tcases[] = {
+ {&dir_fd, &testfile, 0},
+ {&bad_fd, &abs_path, 0},
+ {&atcwd_fd, &rel_path, 0},
+ {&dir_fd, &testfile, AT_EACCESS},
+ {&bad_fd, &abs_path, AT_EACCESS},
+ {&atcwd_fd, &rel_path, AT_EACCESS},
+ {&atcwd_fd, &sym_path, AT_SYMLINK_NOFOLLOW},
+};
+
+static void verify_faccessat2(unsigned int i)
+{
+ struct tcase *tc = &tcases[i];
+
+ TST_EXP_PASS(faccessat2(*tc->fd, *tc->filename, R_OK, tc->flags),
+ "faccessat2(%d, %s, R_OK, %d)",
+ *tc->fd, *tc->filename, tc->flags);
+}
+
+static void setup(void)
+{
+ char *tmpdir_path = tst_get_tmpdir();
+
+ abs_path = tst_aprintf("%s/%s", tmpdir_path, RELPATH);
+ free(tmpdir_path);
+
+ SAFE_MKDIR(TESTDIR, 0777);
+ dir_fd = SAFE_OPEN(TESTDIR, O_DIRECTORY);
+ SAFE_TOUCH(abs_path, 0444, NULL);
+ SAFE_SYMLINK(abs_path, TESTSYMLINK);
+}
+
+static void cleanup(void)
+{
+ if (dir_fd > -1)
+ SAFE_CLOSE(dir_fd);
+}
+
+static struct tst_test test = {
+ .test = verify_faccessat2,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .bufs = (struct tst_buffers []) {
+ {&testfile, .str = TESTFILE},
+ {&rel_path, .str = RELPATH},
+ {&sym_path, .str = TESTSYMLINK},
+ {},
+ },
+ .needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/faccessat2/faccessat202.c b/testcases/kernel/syscalls/faccessat2/faccessat202.c
new file mode 100644
index 000000000..a60db2bf8
--- /dev/null
+++ b/testcases/kernel/syscalls/faccessat2/faccessat202.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test basic error handling of faccessat2 syscall:
+ *
+ * - faccessat2() fails with EFAULT if pathname is a bad pathname point.
+ * - faccessat2() fails with EINVAL if flags is -1.
+ * - faccessat2() fails with EINVAL if mode is -1.
+ * - faccessat2() fails with EBADF if dirfd is -1.
+ * - faccessat2() fails with ENOTDIR if pathname is relative path to a
+ * file and dir_fd is file descriptor for this file.
+ * - faccessat2() fails with EACCES if flags is AT_EACCESS and not using
+ * the effective user and group IDs.
+ *
+ * Minimum Linux version required is v5.8.
+ */
+
+#include <pwd.h>
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/faccessat.h"
+
+#define TESTUSER "nobody"
+#define TESTDIR "faccessat2dir"
+#define RELPATH "faccessat2dir/faccessat2file"
+
+static int fd;
+static int bad_fd = -1;
+static int atcwd_fd = AT_FDCWD;
+static char *bad_path;
+static char *rel_path;
+
+static struct passwd *ltpuser;
+
+static struct tcase {
+ int *fd;
+ char **filename;
+ int mode;
+ int flags;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ {&atcwd_fd, &bad_path, R_OK, 0, EFAULT, "invalid address"},
+ {&atcwd_fd, &rel_path, R_OK, -1, EINVAL, "invalid flags"},
+ {&atcwd_fd, &rel_path, -1, 0, EINVAL, "invalid mode"},
+ {&bad_fd, &rel_path, R_OK, 0, EBADF, "invalid fd"},
+ {&fd, &rel_path, R_OK, 0, ENOTDIR, "fd pointing to file"},
+ {&atcwd_fd, &rel_path, R_OK, AT_EACCESS, EACCES,
+ "AT_EACCESS and unprivileged EUID"},
+};
+
+static void verify_faccessat2(unsigned int i)
+{
+ struct tcase *tc = &tcases[i];
+
+ if (tc->exp_errno == EACCES)
+ SAFE_SETEUID(ltpuser->pw_uid);
+
+ TST_EXP_FAIL(faccessat2(*tc->fd, *tc->filename, tc->mode, tc->flags),
+ tc->exp_errno, "faccessat2() with %s", tc->desc);
+
+ if (tc->exp_errno == EACCES)
+ SAFE_SETEUID(0);
+}
+
+static void setup(void)
+{
+ SAFE_MKDIR(TESTDIR, 0666);
+ SAFE_TOUCH(RELPATH, 0444, NULL);
+
+ fd = SAFE_OPEN(RELPATH, O_RDONLY);
+ bad_path = tst_get_bad_addr(NULL);
+
+ ltpuser = SAFE_GETPWNAM(TESTUSER);
+}
+
+static void cleanup(void)
+{
+ if (fd > -1)
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .test = verify_faccessat2,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .bufs = (struct tst_buffers []) {
+ {&rel_path, .str = RELPATH},
+ {},
+ },
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h
index 51078103e..75a081dc9 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify.h
+++ b/testcases/kernel/syscalls/fanotify/fanotify.h
@@ -72,6 +72,10 @@ static inline int safe_fanotify_mark(const char *file, const int lineno,
#define MAX_HANDLE_SZ 128
#endif
+#ifndef AT_HANDLE_FID
+#define AT_HANDLE_FID 0x200
+#endif
+
/*
* Helper function used to obtain fsid and file_handle for a given path.
* Used by test files correlated to FAN_REPORT_FID functionality.
@@ -260,10 +264,27 @@ static inline int fanotify_mark_supported_by_kernel(uint64_t flag)
return rval;
}
+static inline int fanotify_handle_supported_by_kernel(int flag)
+{
+ /*
+ * On Kernel that does not support AT_HANDLE_FID this will result
+ * with EINVAL. On older kernels, this will result in EBADF.
+ */
+ if (name_to_handle_at(-1, "", NULL, NULL, AT_EMPTY_PATH | flag)) {
+ if (errno == EINVAL)
+ return -1;
+ }
+ return 0;
+}
+
#define REQUIRE_MARK_TYPE_SUPPORTED_BY_KERNEL(mark_type) \
fanotify_init_flags_err_msg(#mark_type, __FILE__, __LINE__, tst_brk_, \
fanotify_mark_supported_by_kernel(mark_type))
+#define REQUIRE_HANDLE_TYPE_SUPPORTED_BY_KERNEL(handle_type) \
+ fanotify_init_flags_err_msg(#handle_type, __FILE__, __LINE__, tst_brk_, \
+ fanotify_handle_supported_by_kernel(handle_type))
+
#define REQUIRE_FANOTIFY_EVENTS_SUPPORTED_ON_FS(init_flags, mark_type, mask, fname) do { \
if (mark_type) \
REQUIRE_MARK_TYPE_SUPPORTED_BY_KERNEL(mark_type); \
diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c
index c3daaf3a2..a25a360fd 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify13.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify13.c
@@ -25,6 +25,7 @@
#include <sys/statfs.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/mount.h>
#include <errno.h>
#include <unistd.h>
#include "tst_test.h"
@@ -37,7 +38,7 @@
#define DIR_ONE "dir_one"
#define FILE_ONE "file_one"
#define FILE_TWO "file_two"
-#define MOUNT_PATH "mntpoint"
+#define MOUNT_PATH "tstmnt"
#define EVENT_MAX ARRAY_SIZE(objects)
#define DIR_PATH_ONE MOUNT_PATH"/"DIR_ONE
#define FILE_PATH_ONE MOUNT_PATH"/"FILE_ONE
@@ -88,6 +89,8 @@ static struct test_case_t {
}
};
+static int ovl_mounted;
+static int bind_mounted;
static int nofid_fd;
static int fanotify_fd;
static int filesystem_mark_unsupported;
@@ -143,8 +146,13 @@ static void do_test(unsigned int number)
struct fanotify_mark_type *mark = &tc->mark;
tst_res(TINFO,
- "Test #%d: FAN_REPORT_FID with mark flag: %s",
- number, mark->name);
+ "Test #%d.%d: FAN_REPORT_FID with mark flag: %s",
+ number, tst_variant, mark->name);
+
+ if (tst_variant && !ovl_mounted) {
+ tst_res(TCONF, "overlayfs not supported on %s", tst_device->fs_type);
+ return;
+ }
if (filesystem_mark_unsupported && mark->flag & FAN_MARK_FILESYSTEM) {
tst_res(TCONF, "FAN_MARK_FILESYSTEM not supported in kernel?");
@@ -160,6 +168,15 @@ static void do_test(unsigned int number)
if (setup_marks(fanotify_fd, tc) != 0)
goto out;
+ /* Variant #1: watching upper fs - open files on overlayfs */
+ if (tst_variant == 1) {
+ if (mark->flag & FAN_MARK_MOUNT) {
+ tst_res(TCONF, "overlayfs upper fs cannot be watched with mount mark");
+ goto out;
+ }
+ SAFE_MOUNT(OVL_MNT, MOUNT_PATH, "none", MS_BIND, NULL);
+ }
+
/* Generate sequence of FAN_OPEN events on objects */
for (i = 0; i < ARRAY_SIZE(objects); i++)
fds[i] = SAFE_OPEN(objects[i].path, O_RDONLY);
@@ -174,6 +191,9 @@ static void do_test(unsigned int number)
SAFE_CLOSE(fds[i]);
}
+ if (tst_variant == 1)
+ SAFE_UMOUNT(MOUNT_PATH);
+
/* Read events from event queue */
len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE);
@@ -261,7 +281,32 @@ out:
static void do_setup(void)
{
- REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_FID, MOUNT_PATH);
+ const char *mnt;
+
+ /*
+ * Bind mount to either base fs or to overlayfs over base fs:
+ * Variant #0: watch base fs - open files on base fs
+ * Variant #1: watch upper fs - open files on overlayfs
+ *
+ * Variant #1 tests a bug whose fix bc2473c90fca ("ovl: enable fsnotify
+ * events on underlying real files") in kernel 6.5 is not likely to be
+ * backported to older kernels.
+ * To avoid waiting for events that won't arrive when testing old kernels,
+ * require that kernel supports encoding fid with new flag AT_HADNLE_FID,
+ * also merged to 6.5 and not likely to be backported to older kernels.
+ */
+ if (tst_variant) {
+ REQUIRE_HANDLE_TYPE_SUPPORTED_BY_KERNEL(AT_HANDLE_FID);
+ ovl_mounted = TST_MOUNT_OVERLAY();
+ mnt = OVL_UPPER;
+ } else {
+ mnt = OVL_BASE_MNTPOINT;
+
+ }
+ REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_FID, mnt);
+ SAFE_MKDIR(MOUNT_PATH, 0755);
+ SAFE_MOUNT(mnt, MOUNT_PATH, "none", MS_BIND, NULL);
+ bind_mounted = 1;
filesystem_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_FILESYSTEM);
@@ -287,19 +332,27 @@ static void do_cleanup(void)
SAFE_CLOSE(nofid_fd);
if (fanotify_fd > 0)
SAFE_CLOSE(fanotify_fd);
+ if (bind_mounted) {
+ SAFE_UMOUNT(MOUNT_PATH);
+ SAFE_RMDIR(MOUNT_PATH);
+ }
+ if (ovl_mounted)
+ SAFE_UMOUNT(OVL_MNT);
}
static struct tst_test test = {
.test = do_test,
.tcnt = ARRAY_SIZE(test_cases),
+ .test_variants = 2,
.setup = do_setup,
.cleanup = do_cleanup,
.needs_root = 1,
.mount_device = 1,
- .mntpoint = MOUNT_PATH,
+ .mntpoint = OVL_BASE_MNTPOINT,
.all_filesystems = 1,
.tags = (const struct tst_tag[]) {
{"linux-git", "c285a2f01d69"},
+ {"linux-git", "bc2473c90fca"},
{}
}
};
diff --git a/testcases/kernel/syscalls/fanotify/fanotify14.c b/testcases/kernel/syscalls/fanotify/fanotify14.c
index bfa0349fe..4596511f0 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify14.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify14.c
@@ -19,6 +19,9 @@
*
* ceaf69f8eadc fanotify: do not allow setting dirent events in mask of non-dir
* 8698e3bab4dd fanotify: refine the validation checks on non-dir inode mask
+ *
+ * The pipes test cases are regression tests for commit:
+ * 69562eb0bd3e fanotify: disallow mount/sb marks on kernel internal pseudo fs
*/
#define _GNU_SOURCE
@@ -40,6 +43,7 @@
#define FLAGS_DESC(flags) {(flags), (#flags)}
+static int pipes[2] = {-1, -1};
static int fanotify_fd;
static int fan_report_target_fid_unsupported;
static int ignore_mark_unsupported;
@@ -60,94 +64,179 @@ static struct test_case_t {
/* when mask.flags == 0, fanotify_init() is expected to fail */
struct test_case_flags_t mask;
int expected_errno;
+ int *pfd;
} test_cases[] = {
/* FAN_REPORT_FID without class FAN_CLASS_NOTIF is not valid */
- {FLAGS_DESC(FAN_CLASS_CONTENT | FAN_REPORT_FID), {}, {}, EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_CONTENT | FAN_REPORT_FID),
+ .expected_errno = EINVAL,
+ },
/* FAN_REPORT_FID without class FAN_CLASS_NOTIF is not valid */
- {FLAGS_DESC(FAN_CLASS_PRE_CONTENT | FAN_REPORT_FID), {}, {}, EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_PRE_CONTENT | FAN_REPORT_FID),
+ .expected_errno = EINVAL,
+ },
/* INODE_EVENTS in mask without class FAN_REPORT_FID are not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF), FLAGS_DESC(0), FLAGS_DESC(INODE_EVENTS),
- EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF),
+ .mark = FLAGS_DESC(FAN_MARK_INODE),
+ .mask = FLAGS_DESC(INODE_EVENTS),
+ .expected_errno = EINVAL,
+ },
/* INODE_EVENTS in mask with FAN_MARK_MOUNT are not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_FID),
- FLAGS_DESC(FAN_MARK_MOUNT), FLAGS_DESC(INODE_EVENTS), EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_FID),
+ .mark = FLAGS_DESC(FAN_MARK_MOUNT),
+ .mask = FLAGS_DESC(INODE_EVENTS),
+ .expected_errno = EINVAL,
+ },
/* FAN_REPORT_NAME without FAN_REPORT_DIR_FID is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_NAME), {}, {}, EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_NAME),
+ .expected_errno = EINVAL,
+ },
/* FAN_REPORT_NAME without FAN_REPORT_DIR_FID is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_FID | FAN_REPORT_NAME), {},
- {}, EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_FID | FAN_REPORT_NAME),
+ .expected_errno = EINVAL,
+ },
/* FAN_REPORT_TARGET_FID without FAN_REPORT_FID is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_TARGET_FID | FAN_REPORT_DFID_NAME),
- {}, {}, EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_TARGET_FID | FAN_REPORT_DFID_NAME),
+ .expected_errno = EINVAL,
+ },
/* FAN_REPORT_TARGET_FID without FAN_REPORT_NAME is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_TARGET_FID | FAN_REPORT_DFID_FID),
- {}, {}, EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_TARGET_FID | FAN_REPORT_DFID_FID),
+ .expected_errno = EINVAL,
+ },
/* FAN_RENAME without FAN_REPORT_NAME is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_FID), FLAGS_DESC(0),
- FLAGS_DESC(FAN_RENAME), EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_FID),
+ .mark = FLAGS_DESC(FAN_MARK_INODE),
+ .mask = FLAGS_DESC(FAN_RENAME),
+ .expected_errno = EINVAL,
+ },
/* With FAN_MARK_ONLYDIR on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF), FLAGS_DESC(FAN_MARK_ONLYDIR),
- FLAGS_DESC(FAN_OPEN), ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF),
+ .mark = FLAGS_DESC(FAN_MARK_ONLYDIR),
+ .mask = FLAGS_DESC(FAN_OPEN),
+ .expected_errno = ENOTDIR,
+ },
/* With FAN_REPORT_TARGET_FID, FAN_DELETE on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
- FLAGS_DESC(0), FLAGS_DESC(FAN_DELETE), ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
+ .mark = FLAGS_DESC(FAN_MARK_INODE),
+ .mask = FLAGS_DESC(FAN_DELETE),
+ .expected_errno = ENOTDIR,
+ },
/* With FAN_REPORT_TARGET_FID, FAN_RENAME on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
- FLAGS_DESC(0), FLAGS_DESC(FAN_RENAME), ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
+ .mark = FLAGS_DESC(FAN_MARK_INODE),
+ .mask = FLAGS_DESC(FAN_RENAME),
+ .expected_errno = ENOTDIR,
+ },
/* With FAN_REPORT_TARGET_FID, FAN_ONDIR on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
- FLAGS_DESC(0), FLAGS_DESC(FAN_OPEN | FAN_ONDIR), ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
+ .mark = FLAGS_DESC(FAN_MARK_INODE),
+ .mask = FLAGS_DESC(FAN_OPEN | FAN_ONDIR),
+ .expected_errno = ENOTDIR,
+ },
/* With FAN_REPORT_TARGET_FID, FAN_EVENT_ON_CHILD on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
- FLAGS_DESC(0), FLAGS_DESC(FAN_OPEN | FAN_EVENT_ON_CHILD),
- ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
+ .mark = FLAGS_DESC(FAN_MARK_INODE),
+ .mask = FLAGS_DESC(FAN_OPEN | FAN_EVENT_ON_CHILD),
+ .expected_errno = ENOTDIR,
+ },
/* FAN_MARK_IGNORE_SURV with FAN_DELETE on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
- FLAGS_DESC(FAN_MARK_IGNORE_SURV), FLAGS_DESC(FAN_DELETE),
- ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
+ .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
+ .mask = FLAGS_DESC(FAN_DELETE),
+ .expected_errno = ENOTDIR,
+ },
/* FAN_MARK_IGNORE_SURV with FAN_RENAME on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
- FLAGS_DESC(FAN_MARK_IGNORE_SURV), FLAGS_DESC(FAN_RENAME),
- ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
+ .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
+ .mask = FLAGS_DESC(FAN_RENAME),
+ .expected_errno = ENOTDIR,
+ },
/* FAN_MARK_IGNORE_SURV with FAN_ONDIR on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
- FLAGS_DESC(FAN_MARK_IGNORE_SURV),
- FLAGS_DESC(FAN_OPEN | FAN_ONDIR), ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
+ .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
+ .mask = FLAGS_DESC(FAN_OPEN | FAN_ONDIR),
+ .expected_errno = ENOTDIR,
+ },
/* FAN_MARK_IGNORE_SURV with FAN_EVENT_ON_CHILD on non-dir is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
- FLAGS_DESC(FAN_MARK_IGNORE_SURV),
- FLAGS_DESC(FAN_OPEN | FAN_EVENT_ON_CHILD), ENOTDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
+ .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
+ .mask = FLAGS_DESC(FAN_OPEN | FAN_EVENT_ON_CHILD),
+ .expected_errno = ENOTDIR,
+ },
/* FAN_MARK_IGNORE without FAN_MARK_IGNORED_SURV_MODIFY on directory is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF), FLAGS_DESC(FAN_MARK_IGNORE),
- FLAGS_DESC(FAN_OPEN), EISDIR},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF),
+ .mark = FLAGS_DESC(FAN_MARK_IGNORE),
+ .mask = FLAGS_DESC(FAN_OPEN),
+ .expected_errno = EISDIR,
+ },
/* FAN_MARK_IGNORE without FAN_MARK_IGNORED_SURV_MODIFY on mount mark is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF),
- FLAGS_DESC(FAN_MARK_MOUNT | FAN_MARK_IGNORE),
- FLAGS_DESC(FAN_OPEN), EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF),
+ .mark = FLAGS_DESC(FAN_MARK_MOUNT | FAN_MARK_IGNORE),
+ .mask = FLAGS_DESC(FAN_OPEN),
+ .expected_errno = EINVAL,
+ },
/* FAN_MARK_IGNORE without FAN_MARK_IGNORED_SURV_MODIFY on filesystem mark is not valid */
- {FLAGS_DESC(FAN_CLASS_NOTIF),
- FLAGS_DESC(FAN_MARK_FILESYSTEM | FAN_MARK_IGNORE),
- FLAGS_DESC(FAN_OPEN), EINVAL},
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF),
+ .mark = FLAGS_DESC(FAN_MARK_FILESYSTEM | FAN_MARK_IGNORE),
+ .mask = FLAGS_DESC(FAN_OPEN),
+ .expected_errno = EINVAL,
+ },
+ /* mount mark on anonymous pipe is not valid */
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF),
+ .mark = FLAGS_DESC(FAN_MARK_MOUNT),
+ .mask = { FAN_ACCESS, "anonymous pipe"},
+ .pfd = pipes,
+ .expected_errno = EINVAL,
+ },
+ /* filesystem mark on anonymous pipe is not valid */
+ {
+ .init = FLAGS_DESC(FAN_CLASS_NOTIF),
+ .mark = FLAGS_DESC(FAN_MARK_FILESYSTEM),
+ .mask = { FAN_ACCESS, "anonymous pipe"},
+ .pfd = pipes,
+ .expected_errno = EINVAL,
+ },
};
static void do_test(unsigned int number)
@@ -185,11 +274,17 @@ static void do_test(unsigned int number)
/* Set mark on non-dir only when expecting error ENOTDIR */
const char *path = tc->expected_errno == ENOTDIR ? FILE1 : MNTPOINT;
+ int dirfd = AT_FDCWD;
+
+ if (tc->pfd) {
+ dirfd = tc->pfd[0];
+ path = NULL;
+ }
- tst_res(TINFO, "Testing fanotify_mark(FAN_MARK_ADD | %s, %s)",
+ tst_res(TINFO, "Testing %s with %s",
tc->mark.desc, tc->mask.desc);
TST_EXP_FD_OR_FAIL(fanotify_mark(fanotify_fd, FAN_MARK_ADD | tc->mark.flags,
- tc->mask.flags, AT_FDCWD, path),
+ tc->mask.flags, dirfd, path),
tc->expected_errno);
/*
@@ -231,12 +326,18 @@ static void do_setup(void)
/* Create temporary test file to place marks on */
SAFE_FILE_PRINTF(FILE1, "0");
+ /* Create anonymous pipes to place marks on */
+ SAFE_PIPE2(pipes, O_CLOEXEC);
}
static void do_cleanup(void)
{
if (fanotify_fd > 0)
SAFE_CLOSE(fanotify_fd);
+ if (pipes[0] != -1)
+ SAFE_CLOSE(pipes[0]);
+ if (pipes[1] != -1)
+ SAFE_CLOSE(pipes[1]);
}
static struct tst_test test = {
@@ -251,6 +352,7 @@ static struct tst_test test = {
.tags = (const struct tst_tag[]) {
{"linux-git", "ceaf69f8eadc"},
{"linux-git", "8698e3bab4dd"},
+ {"linux-git", "69562eb0bd3e"},
{}
}
};
diff --git a/testcases/kernel/syscalls/fanotify/fanotify22.c b/testcases/kernel/syscalls/fanotify/fanotify22.c
index 6596a69c9..a654e8912 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify22.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify22.c
@@ -41,6 +41,7 @@
#define MOUNT_PATH "test_mnt"
#define BASE_DIR "internal_dir"
#define BAD_DIR BASE_DIR"/bad_dir"
+#define BAD_LINK BASE_DIR"/bad_link"
#ifdef HAVE_NAME_TO_HANDLE_AT
@@ -50,6 +51,7 @@ static int fd_notify;
/* These expected FIDs are common to multiple tests */
static struct fanotify_fid_t null_fid;
static struct fanotify_fid_t bad_file_fid;
+static struct fanotify_fid_t bad_link_fid;
static void trigger_fs_abort(void)
{
@@ -64,7 +66,7 @@ static void do_debugfs_request(const char *dev, char *request)
SAFE_CMD(cmd, NULL, NULL);
}
-static void tcase2_trigger_lookup(void)
+static void trigger_bad_file_lookup(void)
{
int ret;
@@ -75,15 +77,27 @@ static void tcase2_trigger_lookup(void)
ret, BAD_DIR, errno, EUCLEAN);
}
+static void trigger_bad_link_lookup(void)
+{
+ int ret;
+
+ /* SAFE_OPEN cannot be used here because we expect it to fail. */
+ ret = open(MOUNT_PATH"/"BAD_LINK, O_RDONLY, 0);
+ if (ret != -1 && errno != EUCLEAN)
+ tst_res(TFAIL, "Unexpected open result(%d) of %s (%d!=%d)",
+ ret, BAD_LINK, errno, EUCLEAN);
+}
+
+
static void tcase3_trigger(void)
{
- trigger_fs_abort();
- tcase2_trigger_lookup();
+ trigger_bad_link_lookup();
+ trigger_bad_file_lookup();
}
static void tcase4_trigger(void)
{
- tcase2_trigger_lookup();
+ trigger_bad_file_lookup();
trigger_fs_abort();
}
@@ -103,7 +117,7 @@ static struct test_case {
},
{
.name = "Lookup of inode with invalid mode",
- .trigger_error = &tcase2_trigger_lookup,
+ .trigger_error = &trigger_bad_file_lookup,
.error_count = 1,
.error = EFSCORRUPTED,
.fid = &bad_file_fid,
@@ -112,8 +126,8 @@ static struct test_case {
.name = "Multiple error submission",
.trigger_error = &tcase3_trigger,
.error_count = 2,
- .error = ESHUTDOWN,
- .fid = &null_fid,
+ .error = EFSCORRUPTED,
+ .fid = &bad_link_fid,
},
{
.name = "Multiple error submission 2",
@@ -247,6 +261,9 @@ static void do_test(unsigned int i)
FAN_FS_ERROR, AT_FDCWD, MOUNT_PATH);
check_event(event_buf, read_len, tcase);
+ /* Unmount and mount the filesystem to get it out of the error state */
+ SAFE_UMOUNT(MOUNT_PATH);
+ SAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type, 0, NULL);
}
static void pre_corrupt_fs(void)
@@ -255,9 +272,11 @@ static void pre_corrupt_fs(void)
SAFE_MKDIR(MOUNT_PATH"/"BAD_DIR, 0777);
fanotify_save_fid(MOUNT_PATH"/"BAD_DIR, &bad_file_fid);
+ fanotify_save_fid(MOUNT_PATH"/"BASE_DIR, &bad_link_fid);
SAFE_UMOUNT(MOUNT_PATH);
do_debugfs_request(tst_device->dev, "sif " BAD_DIR " mode 0xff");
+ do_debugfs_request(tst_device->dev, "ln <1> " BAD_LINK);
SAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type, 0, NULL);
}
diff --git a/testcases/kernel/syscalls/fanotify/fanotify23.c b/testcases/kernel/syscalls/fanotify/fanotify23.c
index 89fd4f36a..fb812c51e 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify23.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify23.c
@@ -160,10 +160,16 @@ static void test_fanotify(void)
}
/*
- * drop_caches should evict inode from cache and remove evictable mark
+ * drop_caches should evict inode from cache and remove evictable mark.
+ * We call drop_caches twice as once the dentries will just cycle
+ * through the LRU without being reclaimed and if there are no other
+ * objects to reclaim, the slab reclaim will just stop instead of
+ * retrying. Note that this relies on how reclaim of fs objects work
+ * for the filesystem but this test is restricted to ext2...
*/
fsync_file(TEST_FILE);
SAFE_FILE_PRINTF(DROP_CACHES_FILE, "3");
+ SAFE_FILE_PRINTF(DROP_CACHES_FILE, "3");
verify_mark_removed(TEST_FILE, "after drop_caches");
diff --git a/testcases/kernel/syscalls/fchmod/fchmod02.c b/testcases/kernel/syscalls/fchmod/fchmod02.c
index e60cb33a6..d6abeffce 100644
--- a/testcases/kernel/syscalls/fchmod/fchmod02.c
+++ b/testcases/kernel/syscalls/fchmod/fchmod02.c
@@ -1,18 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
+ */
+
+/*\
+ * [Description]
*
- * Test Description:
- * Verify that, fchmod() will succeed to change the mode of a file/directory
- * set the sticky bit on it if invoked by root (uid = 0) process with
- * the following constraints,
- * - the process is not the owner of the file/directory.
- * - the effective group ID or one of the supplementary group ID's of the
- * process is equal to the group ID of the file/directory.
+ * Verify that, fchmod(2) will succeed to change the mode of a file/directory
+ * set the sticky bit on it if invoked by root (uid = 0) process with
+ * the following constraints:
*
- * Expected Result:
- * fchmod() should return value 0 on success and succeeds to set sticky bit
- * on the specified file.
+ * - the process is not the owner of the file/directory
+ * - the effective group ID or one of the supplementary group ID's of the
+ * process is equal to the group ID of the file/directory
*/
#include <pwd.h>
diff --git a/testcases/kernel/syscalls/fchmod/fchmod03.c b/testcases/kernel/syscalls/fchmod/fchmod03.c
index 12a6f5a93..bdd720c37 100644
--- a/testcases/kernel/syscalls/fchmod/fchmod03.c
+++ b/testcases/kernel/syscalls/fchmod/fchmod03.c
@@ -8,10 +8,11 @@
*
* Verify that, fchmod(2) will succeed to change the mode of a file
* and set the sticky bit on it if invoked by non-root (uid != 0)
- * process with the following constraints,
- * - the process is the owner of the file.
- * - the effective group ID or one of the supplementary group ID's of the
- * process is equal to the group ID of the file.
+ * process with the following constraints:
+ *
+ * - the process is the owner of the file
+ * - the effective group ID or one of the supplementary group ID's of the
+ * process is equal to the group ID of the file
*/
#include <pwd.h>
diff --git a/testcases/kernel/syscalls/fchmod/fchmod04.c b/testcases/kernel/syscalls/fchmod/fchmod04.c
index d60cb39b2..4fa69e227 100644
--- a/testcases/kernel/syscalls/fchmod/fchmod04.c
+++ b/testcases/kernel/syscalls/fchmod/fchmod04.c
@@ -8,10 +8,11 @@
*
* Verify that, fchmod(2) will succeed to change the mode of a directory
* and set the sticky bit on it if invoked by non-root (uid != 0) process
- * with the following constraints,
- * - the process is the owner of the directory.
- * - the effective group ID or one of the supplementary group ID's of the
- * process is equal to the group ID of the directory.
+ * with the following constraints:
+ *
+ * - the process is the owner of the directory
+ * - the effective group ID or one of the supplementary group ID's of the
+ * process is equal to the group ID of the directory
*/
#include <pwd.h>
diff --git a/testcases/kernel/syscalls/fchown/fchown02.c b/testcases/kernel/syscalls/fchown/fchown02.c
index d02f5bc92..bd1baf3bb 100644
--- a/testcases/kernel/syscalls/fchown/fchown02.c
+++ b/testcases/kernel/syscalls/fchown/fchown02.c
@@ -10,6 +10,7 @@
* [Description]
*
* Verify that fchown(2) invoked by super-user:
+ *
* - clears setuid and setgid bits set on an executable file
* - preserves setgid bit set on a non-group-executable file
*/
diff --git a/testcases/kernel/syscalls/fcntl/.gitignore b/testcases/kernel/syscalls/fcntl/.gitignore
index 48b36ec34..10cb0995f 100644
--- a/testcases/kernel/syscalls/fcntl/.gitignore
+++ b/testcases/kernel/syscalls/fcntl/.gitignore
@@ -8,8 +8,6 @@
/fcntl04_64
/fcntl05
/fcntl05_64
-/fcntl06
-/fcntl06_64
/fcntl07
/fcntl07_64
/fcntl08
diff --git a/testcases/kernel/syscalls/fcntl/fcntl06.c b/testcases/kernel/syscalls/fcntl/fcntl06.c
deleted file mode 100644
index 8dcc04866..000000000
--- a/testcases/kernel/syscalls/fcntl/fcntl06.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- * fcntl06.c
- *
- * DESCRIPTION
- * Error checking conditions for remote locking of regions of a file.
- *
- * CALLS
- * open(2), write(2), fcntl(2)
- *
- * ALGORITHM
- * Test unlocking sections around a write lock using remote Lock/Unlock
- * call which should all fail.
- *
- * USAGE
- * fcntl06
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * Currently Linux kernel doesn't implement R_GETLK/R_SETLK facility,
- * but this facility seems to be present in other standard flavours of
- * Unix. Currently this program has all the testing done under
- * "#ifdef LINUX_FILE_REGION_LOCK", when Linux implements the regions
- * locking then, this testcase should be recompiled accordingly with the
- * "ifdef" removed.
- */
-
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "test.h"
-
-#define F_RGETLK 10 /* kludge code */
-#define F_RSETLK 11 /* kludge code */
-
-char *TCID = "fcntl06";
-int TST_TOTAL = 1;
-
-void setup();
-void cleanup();
-
-#define STRINGSIZE 27
-#define STRING "abcdefghijklmnopqrstuvwxyz\n"
-
-int fd;
-void unlock_file();
-int do_lock(int, short, short, int, int);
-
-int main(int ac, char **av)
-{
- int fail = 0;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup(); /* global setup */
-
- fail = 0;
-
-#ifdef LINUX_FILE_REGION_LOCK
- if (fcntl(fd, F_RGETLK, &tl) == -1) {
- if (errno == EINVAL)
- tst_brkm(TCONF, cleanup,
- "fcntl remote locking feature not implemented in "
- "the kernel");
- else {
- /*
- * FIXME (garrcoop): having it always pass on
- * non-EINVAL is a bad test.
- */
- tst_resm(TPASS, "fcntl on file failed");
- }
- }
-
- /*
- * Add a write lock to the middle of the file and unlock a section
- * just before the lock
- */
- if (do_lock(F_RSETLK, F_WRLCK, 0, 10, 5) == -1)
- tst_resm(TFAIL, "F_RSETLK WRLCK failed");
-
- if (do_lock(F_RSETLK, F_UNLCK, 0, 5, 5) == -1)
- tst_resm(TFAIL | TERRNO, "F_RSETLK UNLOCK failed");
-
- unlock_file();
-#else
- tst_resm(TCONF, "system doesn't have LINUX_LOCK_FILE_REGION support");
-#endif
-
- cleanup();
- tst_exit();
-}
-
-void setup(void)
-{
- char *buf = STRING;
- char template[PATH_MAX];
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- umask(0);
-
- TEST_PAUSE;
-
- tst_tmpdir();
-
- snprintf(template, PATH_MAX, "fcntl06XXXXXX");
-
- if ((fd = mkstemp(template)) == -1)
- tst_resm(TBROK | TERRNO, "mkstemp failed");
-
- if (write(fd, buf, STRINGSIZE) == -1)
- tst_resm(TBROK | TERRNO, "write failed");
-}
-
-int do_lock(int cmd, short type, short whence, int start, int len)
-{
- struct flock fl;
-
- fl.l_type = type;
- fl.l_whence = whence;
- fl.l_start = start;
- fl.l_len = len;
- return (fcntl(fd, cmd, &fl));
-}
-
-void unlock_file(void)
-{
- if (do_lock(F_RSETLK, (short)F_UNLCK, (short)0, 0, 0) == -1) {
- /* Same as FIXME comment above. */
- tst_resm(TPASS | TERRNO, "fcntl on file failed");
- }
-}
-
-void cleanup(void)
-{
-
- if (close(fd) == -1)
- tst_resm(TWARN | TERRNO, "close failed");
-
- tst_rmdir();
-
-}
diff --git a/testcases/kernel/syscalls/fcntl/fcntl11.c b/testcases/kernel/syscalls/fcntl/fcntl11.c
index b66fa8421..d042c6b9b 100644
--- a/testcases/kernel/syscalls/fcntl/fcntl11.c
+++ b/testcases/kernel/syscalls/fcntl/fcntl11.c
@@ -189,11 +189,11 @@ char *str_type(int type)
static char buf[20];
switch (type) {
- case 0:
+ case F_RDLCK:
return ("F_RDLCK");
- case 1:
+ case F_WRLCK:
return ("F_WRLCK");
- case 2:
+ case F_UNLCK:
return ("F_UNLCK");
default:
sprintf(buf, "BAD VALUE: %d", type);
diff --git a/testcases/kernel/syscalls/fcntl/fcntl19.c b/testcases/kernel/syscalls/fcntl/fcntl19.c
index 88c91d6ea..f929aff99 100644
--- a/testcases/kernel/syscalls/fcntl/fcntl19.c
+++ b/testcases/kernel/syscalls/fcntl/fcntl19.c
@@ -215,11 +215,11 @@ char *str_type(int type)
static char buf[20];
switch (type) {
- case 1:
+ case F_RDLCK:
return ("F_RDLCK");
- case 2:
+ case F_WRLCK:
return ("F_WRLCK");
- case 3:
+ case F_UNLCK:
return ("F_UNLCK");
default:
sprintf(buf, "BAD VALUE: %d", type);
diff --git a/testcases/kernel/syscalls/fcntl/fcntl20.c b/testcases/kernel/syscalls/fcntl/fcntl20.c
index b671af8a9..4aa773451 100644
--- a/testcases/kernel/syscalls/fcntl/fcntl20.c
+++ b/testcases/kernel/syscalls/fcntl/fcntl20.c
@@ -214,11 +214,11 @@ char *str_type(int type)
static char buf[20];
switch (type) {
- case 1:
+ case F_RDLCK:
return ("F_RDLCK");
- case 2:
+ case F_WRLCK:
return ("F_WRLCK");
- case 3:
+ case F_UNLCK:
return ("F_UNLCK");
default:
sprintf(buf, "BAD VALUE: %d", type);
diff --git a/testcases/kernel/syscalls/fcntl/fcntl21.c b/testcases/kernel/syscalls/fcntl/fcntl21.c
index 8f1a67cf6..824b8c059 100644
--- a/testcases/kernel/syscalls/fcntl/fcntl21.c
+++ b/testcases/kernel/syscalls/fcntl/fcntl21.c
@@ -222,11 +222,11 @@ char *str_type(int type)
static char buf[20];
switch (type) {
- case 1:
+ case F_RDLCK:
return ("F_RDLCK");
- case 2:
+ case F_WRLCK:
return ("F_WRLCK");
- case 3:
+ case F_UNLCK:
return ("F_UNLCK");
default:
sprintf(buf, "BAD VALUE: %d", type);
diff --git a/testcases/kernel/syscalls/fcntl/fcntl30.c b/testcases/kernel/syscalls/fcntl/fcntl30.c
index c4c3f81f1..64bbb9e3a 100644
--- a/testcases/kernel/syscalls/fcntl/fcntl30.c
+++ b/testcases/kernel/syscalls/fcntl/fcntl30.c
@@ -1,103 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2014 Fujitsu Ltd.
* Author: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com>
- *
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Description:
- * Verify that,
- * Basic test for fcntl(2) using F_SETPIPE_SZ, F_GETPIPE_SZ argument.
+/*\
+ * [Description]
+ *
+ * Verify that, fetching and changing the capacity of a pipe works as
+ * expected with fcntl(2) syscall using F_GETPIPE_SZ, F_SETPIPE_SZ arguments.
*/
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <pwd.h>
-
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
#include "lapi/fcntl.h"
-char *TCID = "fcntl30";
-int TST_TOTAL = 1;
-
-static void setup(void);
-static void cleanup(void);
+static int fds[2];
+static int max_size_unpriv;
-int main(int ac, char **av)
+static void run(void)
{
- int lc;
- int pipe_fds[2], test_fd;
- int orig_pipe_size, new_pipe_size;
+ SAFE_PIPE(fds);
+ TST_EXP_POSITIVE(fcntl(fds[1], F_GETPIPE_SZ));
- tst_parse_opts(ac, av, NULL, NULL);
+ TST_EXP_POSITIVE(fcntl(fds[1], F_SETPIPE_SZ, max_size_unpriv));
+ TST_EXP_POSITIVE(fcntl(fds[1], F_GETPIPE_SZ));
+ TST_EXP_EXPR(TST_RET >= max_size_unpriv,
+ "new pipe size (%ld) >= requested size (%d)",
+ TST_RET, max_size_unpriv);
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- SAFE_PIPE(cleanup, pipe_fds);
- test_fd = pipe_fds[1];
-
- TEST(fcntl(test_fd, F_GETPIPE_SZ));
- if (TEST_RETURN < 0) {
- tst_brkm(TFAIL | TTERRNO, cleanup,
- "fcntl get pipe size failed");
- }
-
- orig_pipe_size = TEST_RETURN;
- new_pipe_size = orig_pipe_size * 2;
- TEST(fcntl(test_fd, F_SETPIPE_SZ, new_pipe_size));
- if (TEST_RETURN < 0) {
- tst_brkm(TFAIL | TTERRNO, cleanup,
- "fcntl test F_SETPIPE_SZ failed");
- }
-
- TEST(fcntl(test_fd, F_GETPIPE_SZ));
- if (TEST_RETURN < 0) {
- tst_brkm(TFAIL | TTERRNO, cleanup,
- "fcntl test F_GETPIPE_SZ failed");
- }
- tst_resm(TINFO, "orig_pipe_size: %d new_pipe_size: %d",
- orig_pipe_size, new_pipe_size);
- if (TEST_RETURN >= new_pipe_size) {
- tst_resm(TPASS, "fcntl test F_GETPIPE_SZ and F_SETPIPE_SZ passed");
- } else {
- tst_resm(TFAIL, "fcntl test F_GETPIPE_SZ and F_SETPIPE_SZ failed");
- }
- SAFE_CLOSE(cleanup, pipe_fds[0]);
- SAFE_CLOSE(cleanup, pipe_fds[1]);
- }
-
- cleanup();
- tst_exit();
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(fds[1]);
}
static void setup(void)
{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ SAFE_FILE_SCANF("/proc/sys/fs/pipe-max-size", "%d", &max_size_unpriv);
}
static void cleanup(void)
{
+ if (fds[0] > 0)
+ SAFE_CLOSE(fds[0]);
+ if (fds[1] > 0)
+ SAFE_CLOSE(fds[1]);
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup
+};
diff --git a/testcases/kernel/syscalls/fcntl/fcntl33.c b/testcases/kernel/syscalls/fcntl/fcntl33.c
index 8d0d1a5a1..3c6a38b81 100644
--- a/testcases/kernel/syscalls/fcntl/fcntl33.c
+++ b/testcases/kernel/syscalls/fcntl/fcntl33.c
@@ -209,7 +209,7 @@ static void cleanup(void)
SAFE_CLOSE(fd);
/* Restore the lease-break-time. */
- FILE_PRINTF(PATH_LS_BRK_T, "%d", ls_brk_t);
+ SAFE_FILE_PRINTF(PATH_LS_BRK_T, "%d", ls_brk_t);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/finit_module/finit_module01.c b/testcases/kernel/syscalls/finit_module/finit_module01.c
index f960b2e40..1929c30fa 100644
--- a/testcases/kernel/syscalls/finit_module/finit_module01.c
+++ b/testcases/kernel/syscalls/finit_module/finit_module01.c
@@ -49,6 +49,7 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.needs_root = 1,
- /* lockdown requires signed modules */
+ /* lockdown and SecureBoot requires signed modules */
.skip_in_lockdown = 1,
+ .skip_in_secureboot = 1,
};
diff --git a/testcases/kernel/syscalls/finit_module/finit_module02.c b/testcases/kernel/syscalls/finit_module/finit_module02.c
index a7434de7d..223d9b388 100644
--- a/testcases/kernel/syscalls/finit_module/finit_module02.c
+++ b/testcases/kernel/syscalls/finit_module/finit_module02.c
@@ -25,7 +25,7 @@
static char *mod_path;
static int fd, fd_zero, fd_invalid = -1, fd_dir;
-static int kernel_lockdown;
+static int kernel_lockdown, secure_boot;
static struct tst_cap cap_req = TST_CAP(TST_CAP_REQ, CAP_SYS_MODULE);
static struct tst_cap cap_drop = TST_CAP(TST_CAP_DROP, CAP_SYS_MODULE);
@@ -83,7 +83,9 @@ static void setup(void)
tst_module_exists(MODULE_NAME, &mod_path);
- kernel_lockdown = tst_lockdown_enabled();
+ kernel_lockdown = tst_lockdown_enabled() > 0;
+ secure_boot = tst_secureboot_enabled() > 0;
+
SAFE_MKDIR(TEST_DIR, 0700);
fd_dir = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
@@ -102,8 +104,8 @@ static void run(unsigned int n)
{
struct tcase *tc = &tcases[n];
- if (tc->skip_in_lockdown && kernel_lockdown) {
- tst_res(TCONF, "Kernel is locked down, skipping %s", tc->name);
+ if (tc->skip_in_lockdown && (kernel_lockdown || secure_boot)) {
+ tst_res(TCONF, "Cannot load unsigned modules, skipping %s", tc->name);
return;
}
diff --git a/testcases/kernel/syscalls/flistxattr/flistxattr01.c b/testcases/kernel/syscalls/flistxattr/flistxattr01.c
index 98a6fa254..68c3948b7 100644
--- a/testcases/kernel/syscalls/flistxattr/flistxattr01.c
+++ b/testcases/kernel/syscalls/flistxattr/flistxattr01.c
@@ -47,7 +47,7 @@ static int has_attribute(const char *list, int llen, const char *attr)
static void verify_flistxattr(void)
{
- char buf[64];
+ char buf[128];
TEST(flistxattr(fd, buf, sizeof(buf)));
if (TST_RET == -1) {
diff --git a/testcases/kernel/syscalls/fork/fork03.c b/testcases/kernel/syscalls/fork/fork03.c
index 25b36c897..c6381dd67 100644
--- a/testcases/kernel/syscalls/fork/fork03.c
+++ b/testcases/kernel/syscalls/fork/fork03.c
@@ -1,119 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: 2001 Ported by Wayne Boyer
*/
-/*
- * NAME
- * fork03.c
- *
- * DESCRIPTION
- * Check that child can use a large text space and do a large
- * number of operations.
- *
- * ALGORITHM
- * Fork one process, check for pid == 0 in child.
- * Check for pid > 0 in parent after wait.
+/*\
+ *[Description]
*
- * USAGE
- * fork03
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * None
+ * Check that child process can use a large text space and do a large number
+ * of operations. In this situation, check for pid == 0 in child and check
+ * for pid > 0 in parent after wait.
*/
-#include <sys/types.h>
+#include <unistd.h>
#include <sys/wait.h>
-#include <stdio.h>
-#include "test.h"
-
-char *TCID = "fork03";
-int TST_TOTAL = 1;
+#include <stdlib.h>
+#include "tst_test.h"
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
+static void verify_fork(void)
{
float fl1, fl2;
- int i;
- int pid1, pid2, status;
-
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- pid1 = fork();
- if (pid1 == -1)
- tst_brkm(TBROK, cleanup, "fork() failed");
-
- if (pid1 == 0) {
- /* child uses some cpu cycles */
- for (i = 1; i < 32767; i++) {
- fl1 = 0.000001;
- fl1 = fl2 = 0.000001;
- fl1 = fl1 * 10.0;
- fl2 = fl1 / 1.232323;
- fl1 = fl2 - fl2;
- fl1 = fl2;
- }
-
- /* Pid must always be zero in child */
- if (pid1 != 0)
- exit(1);
- else
- exit(0);
- } else {
- tst_resm(TINFO, "process id in parent of child from "
- "fork : %d", pid1);
- pid2 = wait(&status); /* wait for child */
-
- if (pid1 != pid2) {
- tst_resm(TFAIL, "pids don't match : %d vs %d",
- pid1, pid2);
- continue;
- }
+ int pid1, pid2, status, i;
+
+ pid1 = SAFE_FORK();
+ if (!pid1) {
+ /* child uses some cpu time slices */
+ for (i = 1; i < 32767; i++) {
+ fl1 = 0.000001;
+ fl1 = fl2 = 0.000001;
+ fl1 = fl1 * 10.0;
+ fl2 = fl1 / 1.232323;
+ fl1 = fl2 - fl2;
+ fl1 = fl2;
+ }
+ exit(!!pid1);
+ }
- if ((status >> 8) != 0) {
- tst_resm(TFAIL, "child exited with failure");
- continue;
- }
+ tst_res(TINFO, "process id in parent of child from fork: %d", pid1);
+ pid2 = SAFE_WAIT(&status);
- tst_resm(TPASS, "test 1 PASSED");
- }
+ if (pid1 != pid2) {
+ tst_res(TFAIL, "pids don't match: %d vs %d", pid1, pid2);
+ return;
}
- cleanup();
- tst_exit();
-}
+ if ((status >> 8) != 0) {
+ tst_res(TFAIL, "child exited with failure");
+ return;
+ }
-static void setup(void)
-{
- tst_sig(FORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
+ tst_res(TPASS, "test PASSED");
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = verify_fork,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/syscalls/fsconfig/.gitignore b/testcases/kernel/syscalls/fsconfig/.gitignore
index 2bc54b827..cfedae5f7 100644
--- a/testcases/kernel/syscalls/fsconfig/.gitignore
+++ b/testcases/kernel/syscalls/fsconfig/.gitignore
@@ -1,2 +1,3 @@
/fsconfig01
/fsconfig02
+/fsconfig03
diff --git a/testcases/kernel/syscalls/fsconfig/fsconfig03.c b/testcases/kernel/syscalls/fsconfig/fsconfig03.c
new file mode 100644
index 000000000..0ba5355d3
--- /dev/null
+++ b/testcases/kernel/syscalls/fsconfig/fsconfig03.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 Alejandro Guerrero <aguerrero@qualys.com>
+ * Copyright (c) 2023 Wei Gao <wegao@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test for CVE-2022-0185.
+ *
+ * References links:
+ *
+ * - https://www.openwall.com/lists/oss-security/2022/01/25/14
+ * - https://github.com/Crusaders-of-Rust/CVE-2022-0185
+ *
+ */
+
+#include "tst_test.h"
+#include "lapi/fsmount.h"
+
+#define MNTPOINT "mntpoint"
+
+static int fd = -1;
+
+static void setup(void)
+{
+ fsopen_supported_by_kernel();
+}
+
+static void run(void)
+{
+ char *val = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ long pagesize;
+
+ TEST(fd = fsopen(tst_device->fs_type, 0));
+ if (fd == -1)
+ tst_brk(TBROK | TTERRNO, "fsopen() failed");
+
+ pagesize = sysconf(_SC_PAGESIZE);
+ if (pagesize == -1)
+ tst_brk(TBROK, "sysconf(_SC_PAGESIZE) failed");
+
+ for (size_t i = 0; i < 5000; i++) {
+ /* use same logic in kernel legacy_parse_param function */
+ const size_t len = i * (strlen(val) + 2) + (strlen(val) + 1) + 2;
+
+ TEST(fsconfig(fd, FSCONFIG_SET_STRING, "\x00", val, 0));
+
+ /* Legacy fsconfig() just copies arguments to buffer */
+ if (!TST_RET && len <= (size_t)pagesize)
+ continue;
+
+ if (!TST_RET) {
+ tst_res(TFAIL, "fsconfig() passed unexpectedly");
+ } else if (TST_RET != -1) {
+ tst_brk(TBROK | TTERRNO,
+ "Invalid fsconfig() return value %ld", TST_RET);
+ } else if (TST_ERR != EINVAL) {
+ tst_res(TFAIL | TTERRNO,
+ "fsconfig() failed with unexpected error");
+ }
+ }
+
+ if (fd != -1)
+ SAFE_CLOSE(fd);
+
+ if (tst_taint_check())
+ tst_res(TFAIL, "kernel has issues on %s",
+ tst_device->fs_type);
+ else
+ tst_res(TPASS, "kernel seems to be fine on %s",
+ tst_device->fs_type);
+}
+
+static void cleanup(void)
+{
+ if (fd >= 0)
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .format_device = 1,
+ .mntpoint = MNTPOINT,
+ .all_filesystems = 1,
+ .taint_check = TST_TAINT_W | TST_TAINT_D,
+ .skip_filesystems = (const char *const []){"fuse", NULL},
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "722d94847de29"},
+ {"CVE", "2022-0185"},
+ {}
+ }
+};
diff --git a/testcases/kernel/syscalls/futex/Makefile b/testcases/kernel/syscalls/futex/Makefile
index 7228496bc..1d05cf115 100644
--- a/testcases/kernel/syscalls/futex/Makefile
+++ b/testcases/kernel/syscalls/futex/Makefile
@@ -9,6 +9,9 @@ futex_wait02: LDLIBS+=-lrt
futex_wake03: LDLIBS+=-lrt
futex_wait05: LDLIBS+=-lrt
futex_wait_bitset01: LDLIBS+=-lrt
+futex_waitv01: LDLIBS+=-lrt
+futex_waitv02: LDLIBS+=-lrt
+futex_waitv03: LDLIBS+=-lrt
futex_wait03: CFLAGS+=-pthread
futex_wake02: CFLAGS+=-pthread
diff --git a/testcases/kernel/syscalls/futex/futex_wake04.c b/testcases/kernel/syscalls/futex/futex_wake04.c
index 176dd4aeb..03d90591b 100644
--- a/testcases/kernel/syscalls/futex/futex_wake04.c
+++ b/testcases/kernel/syscalls/futex/futex_wake04.c
@@ -21,7 +21,6 @@
*/
#include <stdio.h>
-#include <sys/mman.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
diff --git a/testcases/kernel/syscalls/getcpu/getcpu01.c b/testcases/kernel/syscalls/getcpu/getcpu01.c
index f6fcc4fc1..9842c8999 100644
--- a/testcases/kernel/syscalls/getcpu/getcpu01.c
+++ b/testcases/kernel/syscalls/getcpu/getcpu01.c
@@ -69,6 +69,7 @@ static unsigned int get_nodeid(unsigned int cpu_id)
DIR *directory_parent, *directory_node;
struct dirent *de, *dn;
char directory_path[PATH_MAX];
+ char *invalid_number;
unsigned int cpu;
int node_id = 0;
@@ -91,7 +92,9 @@ static unsigned int get_nodeid(unsigned int cpu_id)
while ((dn = readdir(directory_node)) != NULL) {
if (strncmp(dn->d_name, "cpu", 3))
continue;
- cpu = strtoul(dn->d_name + 3, NULL, 0);
+ cpu = strtoul(dn->d_name + 3, &invalid_number, 0);
+ if (strcmp(invalid_number, "\0"))
+ continue;
if (cpu == cpu_id) {
node_id =
strtoul(de->d_name + 4, NULL, 0);
diff --git a/testcases/kernel/syscalls/geteuid/geteuid01.c b/testcases/kernel/syscalls/geteuid/geteuid01.c
index d02fb0a8d..66fb8936c 100644
--- a/testcases/kernel/syscalls/geteuid/geteuid01.c
+++ b/testcases/kernel/syscalls/geteuid/geteuid01.c
@@ -1,87 +1,26 @@
+//SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2003-2023
*
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
+ * Author: William Roske
+ * CO-PILOT: Dave Fenner
*/
-/*
- * AUTHOR : William Roske
- * CO-PILOT : Dave Fenner
+/*\
+ *[Description]
+ *
+ * Check the basic functionality of the geteuid() system call.
*/
-#include <sys/types.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-
-#include "test.h"
-#include "compat_16.h"
-
-static void setup(void);
-static void cleanup(void);
-
-TCID_DEFINE(geteuid01);
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "compat_tst_16.h"
-int main(int ac, char **av)
+static void verify_geteuid(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- TEST(GETEUID(cleanup));
-
- if (TEST_RETURN < 0) {
- tst_resm(TFAIL | TTERRNO, "geteuid failed");
- continue; /* next loop for MTKERNEL */
- }
-
- tst_resm(TPASS, "geteuid returned %ld", TEST_RETURN);
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
+ TST_EXP_POSITIVE(GETEUID(), "geteuid()");
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = verify_geteuid,
+};
diff --git a/testcases/kernel/syscalls/geteuid/geteuid02.c b/testcases/kernel/syscalls/geteuid/geteuid02.c
index e00f81296..eb2272bff 100644
--- a/testcases/kernel/syscalls/geteuid/geteuid02.c
+++ b/testcases/kernel/syscalls/geteuid/geteuid02.c
@@ -1,79 +1,36 @@
+//SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- * Ported by Wayne Boyer
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Ported by Wayne Boyer
*/
-#include <pwd.h>
-#include <errno.h>
-
-#include "test.h"
-#include "compat_16.h"
-
-TCID_DEFINE(geteuid02);
-int TST_TOTAL = 1;
+/*\
+ *[Description]
+ *
+ * Check that geteuid() return value matches value from /proc/self/status.
+ */
-static void setup(void);
-static void cleanup(void);
+#include "tst_test.h"
+#include "compat_tst_16.h"
-int main(int ac, char **av)
+static void verify_geteuid(void)
{
- struct passwd *pwent;
- int lc;
- uid_t uid;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
+ long uid[4];
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
+ TST_EXP_POSITIVE(GETEUID(), "geteuid()");
- TEST(GETEUID(cleanup));
+ if (!TST_PASS)
+ return;
- if (TEST_RETURN == -1)
- tst_brkm(TBROK | TTERRNO, cleanup, "geteuid* failed");
+ SAFE_FILE_LINES_SCANF("/proc/self/status", "Uid: %ld %ld %ld %ld",
+ &uid[0], &uid[1], &uid[2], &uid[3]);
- uid = geteuid();
- pwent = getpwuid(uid);
-
- if (pwent == NULL)
- tst_resm(TFAIL | TERRNO, "getpwuid failed");
-
- UID16_CHECK(pwent->pw_uid, geteuid, cleanup);
- if (pwent->pw_uid != TEST_RETURN)
- tst_resm(TFAIL, "getpwuid value, %d, "
- "does not match geteuid "
- "value, %ld", pwent->pw_uid,
- TEST_RETURN);
- else
- tst_resm(TPASS, "values from geteuid "
- "and getpwuid match");
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
+ TST_EXP_EXPR(TST_RET == uid[1],
+ "geteuid() ret %ld == /proc/self/status EUID: %ld",
+ TST_RET, uid[1]);
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = verify_geteuid,
+};
diff --git a/testcases/kernel/syscalls/getgroups/getgroups01.c b/testcases/kernel/syscalls/getgroups/getgroups01.c
index dc3074b75..cfddeb408 100644
--- a/testcases/kernel/syscalls/getgroups/getgroups01.c
+++ b/testcases/kernel/syscalls/getgroups/getgroups01.c
@@ -95,7 +95,7 @@ int main(int ac, char **av)
/*
* Check that if ngrps is zero that the number of groups is
- * return and the the gidset array is not modified.
+ * return and the gidset array is not modified.
* This is a POSIX special case.
*/
memset(gidset, 052, NGROUPS * sizeof(GID_T));
diff --git a/testcases/kernel/syscalls/gethostname/gethostname01.c b/testcases/kernel/syscalls/gethostname/gethostname01.c
index a7cb5417f..f2276a38c 100644
--- a/testcases/kernel/syscalls/gethostname/gethostname01.c
+++ b/testcases/kernel/syscalls/gethostname/gethostname01.c
@@ -1,161 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000 Silicon Graphics, Inc. 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
+ * Copyright (c) 2023 SUSE LLC Ioannis Bonatakis <ybonatakis@suse.com>
*/
-/* $Id: gethostname01.c,v 1.6 2009/10/26 14:55:47 subrata_modak Exp $ */
-/**********************************************************
- *
- * OS Test - Silicon Graphics, Inc.
- *
- * TEST IDENTIFIER : gethostname01
- *
- * EXECUTED BY : anyone
- *
- * TEST TITLE : Basic test for gethostname(2)
- *
- * PARENT DOCUMENT : usctpl01
- *
- * TEST CASE TOTAL : 1
- *
- * WALL CLOCK TIME : 1
- *
- * CPU TYPES : ALL
- *
- * AUTHOR : William Roske
- *
- * CO-PILOT : Dave Fenner
- *
- * DATE STARTED : 03/30/92
- *
- * INITIAL RELEASE : UNICOS 7.0
- *
- * TEST CASES
- *
- * 1.) gethostname(2) returns...(See Description)
- *
- * INPUT SPECIFICATIONS
- * The standard options for system call tests are accepted.
- * (See the parse_opts(3) man page).
- *
- * DURATION
- * Terminates - with frequency and infinite modes.
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * RESOURCES
- * None
- *
- * ENVIRONMENTAL NEEDS
- * No run-time environmental needs.
- *
- * SPECIAL PROCEDURAL REQUIREMENTS
- * None
- *
- * INTERCASE DEPENDENCIES
- * None
- *
- * DETAILED DESCRIPTION
- * This is a Phase I test for the gethostname(2) system call. It is intended
- * to provide a limited exposure of the system call, for now. It
- * should/will be extended when full functional tests are written for
- * gethostname(2).
- *
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise, Issue a PASS message.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- *
- *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
-
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-
-#include "test.h"
-
-void setup();
-void cleanup();
-
-char *TCID = "gethostname01";
-int TST_TOTAL = 1;
-
-int main(int ac, char **av)
-{
- int lc;
- char hname[100]; /* host name */
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- TEST(gethostname(hname, sizeof(hname)));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL | TTERRNO, "gethostname failed");
- continue; /* next loop for MTKERNEL */
- }
-
- tst_resm(TPASS, "gethostname returned %ld",
- TEST_RETURN);
- }
+/*\
+ * [Description]
+ *
+ * Test is checking that gethostname() succeeds.
+ */
- cleanup();
- tst_exit();
-}
+#include "tst_test.h"
+#include <stdlib.h>
-void setup(void)
+static void run(void)
{
+ char hname[100];
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ TST_EXP_PASS(gethostname(hname, sizeof(hname)));
}
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run
+};
diff --git a/testcases/kernel/syscalls/getpgid/getpgid01.c b/testcases/kernel/syscalls/getpgid/getpgid01.c
index 060486e7e..4c614e0b9 100644
--- a/testcases/kernel/syscalls/getpgid/getpgid01.c
+++ b/testcases/kernel/syscalls/getpgid/getpgid01.c
@@ -1,145 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * NAME
- * getpgid01.c
- *
- * DESCRIPTION
- * Testcase to check the basic functionality of getpgid().
- *
- * ALGORITHM
- * block1: Does getpgid(0), and checks for error.
- * block2: Does getpgid(getpid()) and checks for error.
- * block3: Does getpgid(getppid()) and checks for error.
- * block4: Verifies that getpgid(getpgid(0)) == getpgid(0).
- * block5: Does getpgid(1) and checks for error.
+/*\
+ * [Description]
*
- * USAGE
- * getpgid01
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * Expects that there are no EPERM limitations on getting the
- * process group ID from proc 1 (init).
+ * Verify the basic functionality of getpgid(2) syscall.
*/
-#define _GNU_SOURCE 1
-
-#include <errno.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include "test.h"
-void setup(void);
-void cleanup(void);
+#include "tst_test.h"
-char *TCID = "getpgid01";
-int TST_TOTAL = 1;
-
-int main(int ac, char **av)
+static int get_init_pgid(void)
{
- int lc;
-
- register int pgid_0, pgid_1;
- register int my_pid, my_ppid;
- int ex_stat;
-
- tst_parse_opts(ac, av, NULL, NULL);
+ int pgid;
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- if ((pgid_0 = FORK_OR_VFORK()) == -1)
- tst_brkm(TBROK, cleanup, "fork failed");
- if (pgid_0 > 0) {
- while ((pgid_0 = wait(&ex_stat)) != -1) ;
-
- if (WEXITSTATUS(ex_stat) == 0)
- tst_resm(TPASS, "%s PASSED", TCID);
- else
- tst_resm(TFAIL, "%s FAILED", TCID);
-
- exit(0);
- }
+ SAFE_FILE_SCANF("/proc/1/stat", "%*d %*s %*c %*d %d", &pgid);
+ return pgid;
+}
- if ((pgid_0 = getpgid(0)) == -1)
- tst_resm(TFAIL | TERRNO, "getpgid(0) failed");
- else
- tst_resm(TPASS, "getpgid(0) PASSED");
+static void run(void)
+{
+ pid_t pid_1, child_pid, pgid;
-//block2:
- my_pid = getpid();
- if ((pgid_1 = getpgid(my_pid)) == -1)
- tst_resm(TFAIL | TERRNO, "getpgid(%d) failed", my_pid);
+ pgid = getpgid(0);
+ tst_res(TINFO, "getpgid(0) in parent = %d", pgid);
- if (pgid_0 != pgid_1) {
- tst_resm(TFAIL, "getpgid(my_pid=%d) != getpgid(0) "
- "[%d != %d]", my_pid, pgid_1, pgid_0);
- } else
- tst_resm(TPASS, "getpgid(getpid()) PASSED");
+ pid_1 = SAFE_FORK();
+ if (!pid_1) {
+ child_pid = getpid();
-//block3:
- my_ppid = getppid();
- if ((pgid_1 = getpgid(my_ppid)) == -1)
- tst_resm(TFAIL | TERRNO, "getpgid(%d) failed", my_ppid);
+ tst_res(TINFO, "getpid() in child = %d", child_pid);
+ tst_res(TINFO, "Running getpgid() in child");
- if (pgid_0 != pgid_1) {
- tst_resm(TFAIL, "getpgid(%d) != getpgid(0) [%d != %d]",
- my_ppid, pgid_1, pgid_0);
- } else
- tst_resm(TPASS, "getpgid(getppid()) PASSED");
+ TST_EXP_PID(getpgid(0));
+ TST_EXP_EQ_LI(TST_RET, pgid);
-//block4:
- if ((pgid_1 = getpgid(pgid_0)) < 0)
- tst_resm(TFAIL | TERRNO, "getpgid(%d) failed", pgid_0);
+ TST_EXP_PID(getpgid(child_pid), "getpgid(%d)", child_pid);
+ TST_EXP_EQ_LI(TST_RET, pgid);
- if (pgid_0 != pgid_1) {
- tst_resm(TFAIL, "getpgid(%d) != getpgid(0) [%d != %d]",
- pgid_0, pgid_1, pgid_0);
- } else
- tst_resm(TPASS, "getpgid(%d) PASSED", pgid_0);
+ TST_EXP_PID(getpgid(pgid), "getpgid(%d)", pgid);
+ TST_EXP_EQ_LI(TST_RET, pgid);
-//block5:
- if (getpgid(1) < 0)
- tst_resm(TFAIL | TERRNO, "getpgid(1) failed");
- else
- tst_resm(TPASS, "getpgid(1) PASSED");
+ TST_EXP_PID(getpgid(1));
+ TST_EXP_EQ_LI(TST_RET, get_init_pgid());
}
- cleanup();
- tst_exit();
+ tst_reap_children();
}
-void setup(void)
-{
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-}
-
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1
+};
diff --git a/testcases/kernel/syscalls/getpgid/getpgid02.c b/testcases/kernel/syscalls/getpgid/getpgid02.c
index 92482e3ae..30d0129bc 100644
--- a/testcases/kernel/syscalls/getpgid/getpgid02.c
+++ b/testcases/kernel/syscalls/getpgid/getpgid02.c
@@ -1,137 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * NAME
- * getpgid02.c
- *
- * DESCRIPTION
- * Testcase to check the basic functionality of getpgid().
- *
- * ALGORITHM
- * test 1: Does getpgid(-99) and expects ESRCH.
- * test 2: Searches an unused pid and expects ESRCH.
- *
- * USAGE: <for command-line>
- * getpgid02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+/*\
+ * [Description]
*
- * RESTRICTIONS
- * none
+ * Verify that getpgid(2) fails with errno ESRCH when
+ * pid does not match any process.
*/
-#define _GNU_SOURCE 1
-#include <errno.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include "test.h"
+#include "tst_test.h"
-void setup(void);
-void cleanup(void);
+static pid_t unused_pid;
+static pid_t neg_pid = -99;
-char *TCID = "getpgid02";
-int TST_TOTAL = 2;
-
-int pgid_0, pgid_1;
-#define BADPID -99
-
-struct test_case_t {
- int *id;
- int error;
-} TC[] = {
- /* The pid value is negative */
- {
- &pgid_0, ESRCH},
- /* The pid value does not match any process */
- {
- &pgid_1, ESRCH}
-};
-
-int main(int ac, char **av)
+static void setup(void)
{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- /* loop through the test cases */
- for (i = 0; i < TST_TOTAL; i++) {
-
- TEST(getpgid(*TC[i].id));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "call succeeded unexpectedly");
- continue;
- }
-
- if (TEST_ERRNO == TC[i].error) {
- tst_resm(TPASS, "expected failure - "
- "errno = %d : %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_resm(TFAIL, "unexpected error - %d : %s - "
- "expected %d", TEST_ERRNO,
- strerror(TEST_ERRNO), TC[i].error);
- }
- }
- }
- cleanup();
-
- tst_exit();
+ unused_pid = tst_get_unused_pid();
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
-void setup(void)
+static void run(void)
{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- pgid_0 = BADPID;
-
- pgid_1 = tst_get_unused_pid(cleanup);
+ TST_EXP_FAIL2(getpgid(neg_pid), ESRCH, "getpgid(%d)", neg_pid);
+ TST_EXP_FAIL2(getpgid(unused_pid), ESRCH, "getpgid(%d)", unused_pid);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run
+};
diff --git a/testcases/kernel/syscalls/getpgrp/getpgrp01.c b/testcases/kernel/syscalls/getpgrp/getpgrp01.c
index 61feba8d1..a94736661 100644
--- a/testcases/kernel/syscalls/getpgrp/getpgrp01.c
+++ b/testcases/kernel/syscalls/getpgrp/getpgrp01.c
@@ -1,160 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000 Silicon Graphics, Inc. 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
+ * AUTHOR: William Roske, CO-PILOT: Dave Fenner
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/* $Id: getpgrp01.c,v 1.6 2009/10/26 14:55:47 subrata_modak Exp $ */
-/**********************************************************
- *
- * OS Test - Silicon Graphics, Inc.
- *
- * TEST IDENTIFIER : getpgrp01
- *
- * EXECUTED BY : anyone
- *
- * TEST TITLE : Basic test for getpgrp(2)
- *
- * PARENT DOCUMENT : usctpl01
- *
- * TEST CASE TOTAL : 1
- *
- * WALL CLOCK TIME : 1
- *
- * CPU TYPES : ALL
- *
- * AUTHOR : William Roske
- *
- * CO-PILOT : Dave Fenner
- *
- * DATE STARTED : 03/30/92
- *
- * INITIAL RELEASE : UNICOS 7.0
- *
- * TEST CASES
- *
- * 1.) getpgrp(2) returns...(See Description)
- *
- * INPUT SPECIFICATIONS
- * The standard options for system call tests are accepted.
- * (See the parse_opts(3) man page).
- *
- * OUTPUT SPECIFICATIONS
- *$
- * DURATION
- * Terminates - with frequency and infinite modes.
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * RESOURCES
- * None
- *
- * ENVIRONMENTAL NEEDS
- * No run-time environmental needs.
- *
- * SPECIAL PROCEDURAL REQUIREMENTS
- * None
- *
- * INTERCASE DEPENDENCIES
- * None
- *
- * DETAILED DESCRIPTION
- * This is a Phase I test for the getpgrp(2) system call. It is intended
- * to provide a limited exposure of the system call, for now. It
- * should/will be extended when full functional tests are written for
- * getpgrp(2).
- *
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise, Issue a PASS message.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- *
- *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#include "test.h"
-
-void setup();
-void cleanup();
-
-char *TCID = "getpgrp01";
-int TST_TOTAL = 1;
-
-int main(int ac, char **av)
-{
- int lc;
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- TEST(getpgrp());
-
- if (TEST_RETURN == -1)
- tst_resm(TFAIL | TTERRNO, "getpgrp failed");
- else
- tst_resm(TPASS, "getpgrp returned %ld", TEST_RETURN);
-
- }
+/*\
+ * [Description]
+ *
+ * Verify that getpgrp(2) syscall executes successfully.
+ */
- cleanup();
- tst_exit();
-}
+#include "tst_test.h"
-void setup(void)
+static void run(void)
{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ TST_EXP_PID(getpgrp());
+ TST_EXP_EQ_LI(TST_RET, SAFE_GETPGID(0));
}
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run
+};
diff --git a/testcases/kernel/syscalls/getpid/getpid02.c b/testcases/kernel/syscalls/getpid/getpid02.c
index d826724f4..86ad5a29f 100644
--- a/testcases/kernel/syscalls/getpid/getpid02.c
+++ b/testcases/kernel/syscalls/getpid/getpid02.c
@@ -7,6 +7,7 @@
* [Description]
*
* Check that:
+ *
* - fork() in parent returns the same pid as getpid() in child
* - getppid() in child returns the same pid as getpid() in parent
*/
diff --git a/testcases/kernel/syscalls/getrusage/getrusage04.c b/testcases/kernel/syscalls/getrusage/getrusage04.c
index 06b576d79..b03bc549b 100644
--- a/testcases/kernel/syscalls/getrusage/getrusage04.c
+++ b/testcases/kernel/syscalls/getrusage/getrusage04.c
@@ -104,8 +104,9 @@ int main(int argc, char *argv[])
tst_count = 0;
i = 0;
SAFE_GETRUSAGE(cleanup, RUSAGE_THREAD, &usage);
- tst_resm(TINFO, "utime:%12luus; stime:%12luus",
- usage.ru_utime.tv_usec, usage.ru_stime.tv_usec);
+ tst_resm(TINFO, "utime:%12lldus; stime:%12lldus",
+ (long long)usage.ru_utime.tv_usec,
+ (long long)usage.ru_stime.tv_usec);
ulast = usage.ru_utime.tv_usec;
slast = usage.ru_stime.tv_usec;
@@ -115,9 +116,9 @@ int main(int argc, char *argv[])
sdelta = usage.ru_stime.tv_usec - slast;
if (udelta > 0 || sdelta > 0) {
i++;
- tst_resm(TINFO, "utime:%12luus; stime:%12luus",
- usage.ru_utime.tv_usec,
- usage.ru_stime.tv_usec);
+ tst_resm(TINFO, "utime:%12lldus; stime:%12lldus",
+ (long long)usage.ru_utime.tv_usec,
+ (long long)usage.ru_stime.tv_usec);
if ((long)udelta > 1000 + (BIAS_MAX * factor_nr)) {
sprintf(msg_string,
"utime increased > %ldus:",
diff --git a/testcases/kernel/syscalls/init_module/init_module01.c b/testcases/kernel/syscalls/init_module/init_module01.c
index 79e567cd6..26ff0b93b 100644
--- a/testcases/kernel/syscalls/init_module/init_module01.c
+++ b/testcases/kernel/syscalls/init_module/init_module01.c
@@ -53,6 +53,7 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.needs_root = 1,
- /* lockdown requires signed modules */
+ /* lockdown and SecureBoot requires signed modules */
.skip_in_lockdown = 1,
+ .skip_in_secureboot = 1,
};
diff --git a/testcases/kernel/syscalls/init_module/init_module02.c b/testcases/kernel/syscalls/init_module/init_module02.c
index ad6569a06..e6730e21c 100644
--- a/testcases/kernel/syscalls/init_module/init_module02.c
+++ b/testcases/kernel/syscalls/init_module/init_module02.c
@@ -22,7 +22,7 @@
#define MODULE_NAME "init_module.ko"
static unsigned long size, zero_size;
-static int kernel_lockdown;
+static int kernel_lockdown, secure_boot;
static void *buf, *faulty_buf, *null_buf;
static struct tst_cap cap_req = TST_CAP(TST_CAP_REQ, CAP_SYS_MODULE);
@@ -53,7 +53,8 @@ static void setup(void)
tst_module_exists(MODULE_NAME, NULL);
- kernel_lockdown = tst_lockdown_enabled();
+ kernel_lockdown = tst_lockdown_enabled() > 0;
+ secure_boot = tst_secureboot_enabled() > 0;
fd = SAFE_OPEN(MODULE_NAME, O_RDONLY|O_CLOEXEC);
SAFE_FSTAT(fd, &sb);
size = sb.st_size;
@@ -67,8 +68,8 @@ static void run(unsigned int n)
{
struct tcase *tc = &tcases[n];
- if (tc->skip_in_lockdown && kernel_lockdown) {
- tst_res(TCONF, "Kernel is locked down, skipping %s", tc->name);
+ if (tc->skip_in_lockdown && (kernel_lockdown || secure_boot)) {
+ tst_res(TCONF, "Cannot load unsigned modules, skipping %s", tc->name);
return;
}
diff --git a/testcases/kernel/syscalls/io_uring/io_uring01.c b/testcases/kernel/syscalls/io_uring/io_uring01.c
index 70151bb85..ab1ec00d6 100644
--- a/testcases/kernel/syscalls/io_uring/io_uring01.c
+++ b/testcases/kernel/syscalls/io_uring/io_uring01.c
@@ -264,5 +264,10 @@ static struct tst_test test = {
.bufs = (struct tst_buffers []) {
{&iov, .iov_sizes = (int[]){BLOCK_SZ, -1}},
{}
+ },
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/kernel/io_uring_disabled", "0",
+ TST_SR_SKIP_MISSING | TST_SR_TCONF_RO},
+ {}
}
};
diff --git a/testcases/kernel/syscalls/io_uring/io_uring02.c b/testcases/kernel/syscalls/io_uring/io_uring02.c
index c5c770074..c9d4bbcb1 100644
--- a/testcases/kernel/syscalls/io_uring/io_uring02.c
+++ b/testcases/kernel/syscalls/io_uring/io_uring02.c
@@ -255,6 +255,11 @@ static struct tst_test test = {
TST_CAP(TST_CAP_REQ, CAP_SYS_CHROOT),
{}
},
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/kernel/io_uring_disabled", "0",
+ TST_SR_SKIP_MISSING | TST_SR_TCONF_RO},
+ {}
+ },
.tags = (const struct tst_tag[]) {
{"linux-git", "9392a27d88b9"},
{"linux-git", "ff002b30181d"},
diff --git a/testcases/kernel/syscalls/ioctl/Makefile b/testcases/kernel/syscalls/ioctl/Makefile
index c2ff6c8e7..1d40f5e0b 100644
--- a/testcases/kernel/syscalls/ioctl/Makefile
+++ b/testcases/kernel/syscalls/ioctl/Makefile
@@ -7,6 +7,8 @@ include $(top_srcdir)/include/mk/testcases.mk
INSTALL_TARGETS += test_ioctl
+ioctl01: LDLIBS+=-lutil
+
ifeq ($(ANDROID),1)
FILTER_OUT_MAKE_TARGETS += ioctl02
endif
diff --git a/testcases/kernel/syscalls/ioctl/ioctl01.c b/testcases/kernel/syscalls/ioctl/ioctl01.c
index 2989c0e9b..c84a72b9a 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl01.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl01.c
@@ -2,104 +2,90 @@
/*
* Copyright (c) International Business Machines Corp., 2001
* Copyright (c) 2020 Petr Vorel <petr.vorel@gmail.com>
+ * Copyright (c) Linux Test Project, 2002-2023
* 07/2001 Ported by Wayne Boyer
* 04/2002 Fixes by wjhuie
+ */
+
+/*\
+ * [Description]
*
- * Testcase to check the errnos set by the ioctl(2) system call.
+ * Testcase to check the errnos set by the ioctl(2) system call.
*
- * ALGORITHM
- * 1. EBADF: Pass an invalid fd to ioctl(fd, ..) and expect EBADF.
- * 2. EFAULT: Pass an invalid address of arg in ioctl(fd, .., arg)
- * 3. EINVAL: Pass invalid cmd in ioctl(fd, cmd, arg)
- * 4. ENOTTY: Pass an non-streams fd in ioctl(fd, cmd, arg)
- * 5. EFAULT: Pass a NULL address for termio
+ * - EBADF: Pass an invalid fd to ioctl(fd, ...) and expect EBADF
+ * - EFAULT: Pass an invalid address of arg in ioctl(fd, ..., arg)
+ * - EINVAL: Pass invalid cmd in ioctl(fd, cmd, arg)
+ * - ENOTTY: Pass an non-streams fd in ioctl(fd, cmd, arg)
+ * - EFAULT: Pass a NULL address for termio
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
+#include <pty.h>
#include "tst_test.h"
#include "lapi/ioctl.h"
#define INVAL_IOCTL 9999999
+static int amaster, aslave;
static int fd, fd_file;
static int bfd = -1;
static struct termio termio;
+static struct termios termios;
static struct tcase {
+ const char *desc;
int *fd;
int request;
- struct termio *s_tio;
+ void *s_tio;
int error;
} tcases[] = {
- /* file descriptor is invalid */
- {&bfd, TCGETA, &termio, EBADF},
- /* termio address is invalid */
- {&fd, TCGETA, (struct termio *)-1, EFAULT},
- /* command is invalid */
+ {"File descriptor is invalid (termio)", &bfd, TCGETA, &termio, EBADF},
+ {"File descriptor is invalid (termios)", &bfd, TCGETS, &termios, EBADF},
+ {"Termio address is invalid", &fd, TCGETA, (struct termio *)-1, EFAULT},
+ {"Termios address is invalid", &fd, TCGETS, (struct termios *)-1, EFAULT},
/* This errno value was changed from EINVAL to ENOTTY
* by kernel commit 07d106d0 and bbb63c51
*/
- {&fd, INVAL_IOCTL, &termio, ENOTTY},
- /* file descriptor is for a regular file */
- {&fd_file, TCGETA, &termio, ENOTTY},
- /* termio is NULL */
- {&fd, TCGETA, NULL, EFAULT}
+ {"Command is invalid", &fd, INVAL_IOCTL, &termio, ENOTTY},
+ {"File descriptor is for a regular file (termio)", &fd_file, TCGETA, &termio, ENOTTY},
+ {"File descriptor is for a regular file (termios)", &fd_file, TCGETS, &termios, ENOTTY},
+ {"Termio is NULL", &fd, TCGETA, NULL, EFAULT},
+ {"Termios is NULL", &fd, TCGETS, NULL, EFAULT}
};
-static char *device;
-
static void verify_ioctl(unsigned int i)
{
- TEST(ioctl(*(tcases[i].fd), tcases[i].request, tcases[i].s_tio));
-
- if (TST_RET != -1) {
- tst_res(TFAIL, "call succeeded unexpectedly");
- return;
- }
-
- if (TST_ERR != tcases[i].error) {
- tst_res(TFAIL | TTERRNO,
- "failed unexpectedly; expected %s",
- tst_strerrno(tcases[i].error));
- return;
- }
-
- tst_res(TPASS | TTERRNO, "failed as expected");
+ TST_EXP_FAIL(ioctl(*(tcases[i].fd), tcases[i].request, tcases[i].s_tio),
+ tcases[i].error, "%s", tcases[i].desc);
}
static void setup(void)
{
- unsigned int i;
+ if (openpty(&amaster, &aslave, NULL, NULL, NULL) < 0)
+ tst_brk(TBROK | TERRNO, "unable to open pty");
- if (!device)
- tst_brk(TBROK, "You must specify a tty device with -D option");
-
- fd = SAFE_OPEN(device, O_RDWR, 0777);
+ fd = amaster;
fd_file = SAFE_OPEN("x", O_CREAT, 0777);
}
static void cleanup(void)
{
- if (fd > 0)
- SAFE_CLOSE(fd);
-
+ if (amaster > 0)
+ SAFE_CLOSE(amaster);
+ if (aslave > 0)
+ SAFE_CLOSE(aslave);
if (fd_file > 0)
SAFE_CLOSE(fd_file);
}
static struct tst_test test = {
- .needs_root = 1,
.needs_tmpdir = 1,
.setup = setup,
.cleanup = cleanup,
.test = verify_ioctl,
- .tcnt = ARRAY_SIZE(tcases),
- .options = (struct tst_option[]) {
- {"D:", &device, "Tty device. For example, /dev/tty[0-9]"},
- {}
- }
+ .tcnt = ARRAY_SIZE(tcases)
};
diff --git a/testcases/kernel/syscalls/ioctl/test_ioctl b/testcases/kernel/syscalls/ioctl/test_ioctl
index 923275433..43836a229 100755
--- a/testcases/kernel/syscalls/ioctl/test_ioctl
+++ b/testcases/kernel/syscalls/ioctl/test_ioctl
@@ -41,29 +41,6 @@ case "$device_no" in
[0-9]|[0-9][0-9])
has_tty $tttype
if [ $? -eq 0 ]; then
- tst_resm TINFO "Skipping ioctl01 with $tttype"
- continue
- fi
- tst_resm TINFO "Testing ioctl01 with $tttype"
- ioctl01 -D $tttype
- RC=$?
- if [ $RC -eq 0 ]
- then
- tst_resm TPASS "ioctl01 Passed with $tttype"
- else
- tst_resm TFAIL "ioctl01 Failed with $tttype"
- fi
-echo;;
-esac
-done
-
-for tttype in `ls /dev/tty*`
-do
-device_no=${tttype#/dev/tty}
-case "$device_no" in
-[0-9]|[0-9][0-9])
- has_tty $tttype
- if [ $? -eq 0 ]; then
tst_resm TINFO "Skipping ioctl02 with $tttype"
continue
fi
diff --git a/testcases/kernel/syscalls/ioprio/ioprio.h b/testcases/kernel/syscalls/ioprio/ioprio.h
index c74380475..dbe27c15f 100644
--- a/testcases/kernel/syscalls/ioprio/ioprio.h
+++ b/testcases/kernel/syscalls/ioprio/ioprio.h
@@ -1,33 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2019 Linus Walleij <linus.walleij@linaro.org>
+ * Copyright (c) 2023 Linux Test Project
*/
#ifndef LTP_IOPRIO_H
#define LTP_IOPRIO_H
-enum {
- IOPRIO_CLASS_NONE = 0,
- IOPRIO_CLASS_RT,
- IOPRIO_CLASS_BE,
- IOPRIO_CLASS_IDLE,
-};
-
-enum {
- IOPRIO_WHO_PROCESS = 1,
- IOPRIO_WHO_PGRP,
- IOPRIO_WHO_USER,
-};
-
-/* The I/O scheduler classes have 8 priorities 0..7 except for the IDLE class */
-#define IOPRIO_PRIO_NUM 8
-
-#define IOPRIO_CLASS_SHIFT (13)
-#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
-
-#define IOPRIO_PRIO_CLASS(data) ((data) >> IOPRIO_CLASS_SHIFT)
-#define IOPRIO_PRIO_LEVEL(data) ((data) & IOPRIO_PRIO_MASK)
-#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
+#include "lapi/ioprio.h"
+#include "lapi/syscalls.h"
static const char * const to_class_str[] = {
[IOPRIO_CLASS_NONE] = "NONE",
@@ -46,10 +27,10 @@ static inline int sys_ioprio_set(int which, int who, int ioprio)
return tst_syscall(__NR_ioprio_set, which, who, ioprio);
}
-/* Priority range from 0 (highest) to 7 (lowest) */
+/* Priority range from 0 (highest) to IOPRIO_PRIO_NUM (lowest) */
static inline int prio_in_range(int prio)
{
- if ((prio < 0) || (prio > 7))
+ if ((prio < 0) || (prio >= IOPRIO_PRIO_NUM))
return 0;
return 1;
}
@@ -91,4 +72,4 @@ static inline void ioprio_check_setting(int class, int prio, int report)
newprio);
}
-#endif
+#endif /* LTP_IOPRIO_H */
diff --git a/testcases/kernel/syscalls/ioprio/ioprio_get01.c b/testcases/kernel/syscalls/ioprio/ioprio_get01.c
index 6e822434e..f1325be31 100644
--- a/testcases/kernel/syscalls/ioprio/ioprio_get01.c
+++ b/testcases/kernel/syscalls/ioprio/ioprio_get01.c
@@ -1,16 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2019 Linus Walleij <linus.walleij@linaro.org>
+ * Copyright (c) 2023 Linux Test Project
+ */
+
+/*\
+ * [Description]
*
- * Description:
* Basic ioprio_get() test. Gets the current process I/O priority and
* checks that the values are sane.
*/
-#include <sys/types.h>
-#include <sys/syscall.h>
#include "tst_test.h"
-#include "lapi/syscalls.h"
#include "ioprio.h"
static void run(void)
diff --git a/testcases/kernel/syscalls/ioprio/ioprio_set01.c b/testcases/kernel/syscalls/ioprio/ioprio_set01.c
index 19953ba36..0868cea7c 100644
--- a/testcases/kernel/syscalls/ioprio/ioprio_set01.c
+++ b/testcases/kernel/syscalls/ioprio/ioprio_set01.c
@@ -1,17 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2019 Linus Walleij <linus.walleij@linaro.org>
+ * Copyright (c) 2019-2023 Linux Test Project
+ */
+
+/*\
+ * [Description]
*
- * Description:
* Basic ioprio_set() test. Gets the current process I/O priority and
* bumps it up one notch, then down two notches and checks that the
* new priority is reported back correctly.
*/
-#include <sys/types.h>
-#include <sys/syscall.h>
#include "tst_test.h"
-#include "lapi/syscalls.h"
#include "ioprio.h"
static int orig_class;
diff --git a/testcases/kernel/syscalls/ioprio/ioprio_set02.c b/testcases/kernel/syscalls/ioprio/ioprio_set02.c
index 328a130cb..37db7bf42 100644
--- a/testcases/kernel/syscalls/ioprio/ioprio_set02.c
+++ b/testcases/kernel/syscalls/ioprio/ioprio_set02.c
@@ -1,17 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2019 Linus Walleij <linus.walleij@linaro.org>
+ * Copyright (c) 2023 Linux Test Project
+ */
+
+/*\
+ * [Description]
*
- * Description:
* Extended ioprio_set() test.
* Tests to set all 8 priority levels for best effort priority, then
* switches to test all 8 priority levels for idle priority.
*/
-#include <sys/types.h>
-#include <sys/syscall.h>
#include "tst_test.h"
-#include "lapi/syscalls.h"
#include "ioprio.h"
static void run(void)
diff --git a/testcases/kernel/syscalls/ioprio/ioprio_set03.c b/testcases/kernel/syscalls/ioprio/ioprio_set03.c
index b2c962a6f..6efcacc1c 100644
--- a/testcases/kernel/syscalls/ioprio/ioprio_set03.c
+++ b/testcases/kernel/syscalls/ioprio/ioprio_set03.c
@@ -1,16 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2019 Linus Walleij <linus.walleij@linaro.org>
+ * Copyright (c) 2023 Linux Test Project
+ */
+
+/*\
+ * [Description]
*
- * Description:
* Negative ioprio_set() test. Test some non-working priorities to make
* sure they don't work.
*/
-#include <sys/types.h>
-#include <sys/syscall.h>
#include "tst_test.h"
-#include "lapi/syscalls.h"
#include "ioprio.h"
static void run(void)
@@ -27,7 +28,7 @@ static void run(void)
sys_ioprio_set(IOPRIO_WHO_PROCESS, 0,
IOPRIO_PRIO_VALUE(class, 4));
TEST(sys_ioprio_set(IOPRIO_WHO_PROCESS, 0,
- IOPRIO_PRIO_VALUE(class, 8)));
+ IOPRIO_PRIO_VALUE(class, IOPRIO_PRIO_NUM)));
if (TST_RET == -1) {
ioprio_check_setting(class, 4, 1);
if (errno == EINVAL)
diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c
index 75adcb229..56d1505fd 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl01.c
@@ -6,7 +6,7 @@
*/
/*
- * Test that IPC_STAT command succeeds and the the buffer is filled with
+ * Test that IPC_STAT command succeeds and the buffer is filled with
* correct data.
*/
#include <errno.h>
diff --git a/testcases/kernel/syscalls/ipc/msgget/msgget02.c b/testcases/kernel/syscalls/ipc/msgget/msgget02.c
index ce59a8fb5..1885599d1 100644
--- a/testcases/kernel/syscalls/ipc/msgget/msgget02.c
+++ b/testcases/kernel/syscalls/ipc/msgget/msgget02.c
@@ -8,11 +8,11 @@
*
* Test for EEXIST, ENOENT, EACCES errors.
*
- * 1) msgget(2) fails if a message queue exists for key and msgflg
+ * - msgget(2) fails if a message queue exists for key and msgflg
* specified both IPC_CREAT and IPC_EXCL.
- * 2) msgget(2) fails if no message queue exists for key and msgflg
+ * - msgget(2) fails if no message queue exists for key and msgflg
* did not specify IPC_CREAT.
- * 3) msgget(2) fails if a message queue exists for key, but the
+ * - msgget(2) fails if a message queue exists for key, but the
* calling process does not have permission to access the queue,
* and does not have the CAP_IPC_OWNER capability.
*
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
index 3cb70ab18..aa37d9058 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
@@ -110,11 +110,12 @@ int main(int argc, char **argv)
}
free_pids = tst_get_free_pids(cleanup);
- if (nprocs >= free_pids) {
+ /* Each forked child forks once, take it into account here. */
+ if (nprocs * 2 >= free_pids) {
tst_resm(TINFO,
"Requested number of processes higher than limit (%d > %d), "
- "setting to %d", nprocs, free_pids, free_pids);
- nprocs = free_pids;
+ "setting to %d", nprocs * 2, free_pids, free_pids);
+ nprocs = free_pids / 2;
}
srand(getpid());
diff --git a/testcases/kernel/syscalls/ipc/semget/.gitignore b/testcases/kernel/syscalls/ipc/semget/.gitignore
index ce26c93b0..4519b30d2 100644
--- a/testcases/kernel/syscalls/ipc/semget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/semget/.gitignore
@@ -1,5 +1,3 @@
/semget01
/semget02
-/semget03
/semget05
-/semget06
diff --git a/testcases/kernel/syscalls/ipc/semget/Makefile b/testcases/kernel/syscalls/ipc/semget/Makefile
index 26b9f264d..b1201281d 100644
--- a/testcases/kernel/syscalls/ipc/semget/Makefile
+++ b/testcases/kernel/syscalls/ipc/semget/Makefile
@@ -3,10 +3,10 @@
top_srcdir ?= ../../../../..
-LTPLIBS = ltpipc
+LTPLIBS = ltpnewipc
include $(top_srcdir)/include/mk/testcases.mk
-LTPLDLIBS = -lltpipc
+LTPLDLIBS = -lltpnewipc
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/semget/semget01.c b/testcases/kernel/syscalls/ipc/semget/semget01.c
index 217163b3a..872acabd3 100644
--- a/testcases/kernel/syscalls/ipc/semget/semget01.c
+++ b/testcases/kernel/syscalls/ipc/semget/semget01.c
@@ -1,172 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * NAME
- * semget01.c
- *
- * DESCRIPTION
- * semget01 - test that semget() correclty creates a semaphore set
+/*\
+ * [Description]
*
- * ALGORITHM
- * loop if that option was specified
- * call semget() to create the semaphore set
- * check the return code
- * if failure, issue a FAIL message.
- * otherwise,
- * if doing functionality testing
- * stat the semaphore set
- * if the number of primitive semaphores is correct and
- * the semaphore uid == the process uid
- * then,
- * issue a PASS message
- * otherwise
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- * none
+ * This case checks that semget() correclty creates a semaphore set.
*/
-#include "ipcsem.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include "lapi/sem.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
-char *TCID = "semget01";
-int TST_TOTAL = 1;
+static int sem_id = -1, sem_key = -1;
-int sem_id_1 = -1;
-
-int main(int ac, char **av)
+static void check_functionality(void)
{
- int lc;
- void check_functionality(void);
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup(); /* global setup */
-
- /* The following loop checks looping state if -i option given */
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- /*
- * Use TEST macro to make the call
- */
-
- TEST(semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL, "%s call failed - errno = %d : %s",
- TCID, TEST_ERRNO, strerror(TEST_ERRNO));
- } else {
- /* get the semaphore ID */
- sem_id_1 = TEST_RETURN;
-
- check_functionality();
- }
-
- /*
- * remove the semaphore that was created and mark the ID
- * as invalid.
- */
- if (sem_id_1 != -1) {
- rm_sema(sem_id_1);
- sem_id_1 = -1;
- }
- }
+ struct semid_ds semary;
+ union semun un_arg;
- cleanup();
+ un_arg.buf = &semary;
+ SAFE_SEMCTL(sem_id, 0, IPC_STAT, un_arg);
+ TST_EXP_EQ_LI(un_arg.buf->sem_nsems, PSEMS);
+ TST_EXP_EQ_LI(un_arg.buf->sem_perm.cuid, geteuid());
- tst_exit();
+ tst_res(TPASS, "basic semaphore values are okay");
}
-/*
- * check_functionality() - check the functionality of the tested system call.
- */
-void check_functionality(void)
+static void verify_semget(void)
{
- struct semid_ds semary;
- union semun un_arg; /* union defined in ipcsem.h */
-
- /* STAT the semaphore */
- un_arg.buf = &semary;
- if (semctl(sem_id_1, 0, IPC_STAT, un_arg) == -1) {
- tst_brkm(TBROK, cleanup, "Could not stat the semaphore");
+ TEST(semget(sem_key, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA));
+ if (TST_RET == -1) {
+ tst_res(TFAIL | TTERRNO, "semget() failed");
return;
}
- if (un_arg.buf->sem_nsems != PSEMS) {
- tst_resm(TFAIL, "# of semaphores in set != # given to create");
- return;
- }
+ sem_id = TST_RET;
+ check_functionality();
- if (un_arg.buf->sem_perm.cuid != geteuid()) {
- tst_resm(TFAIL, "semaphore uid != process uid");
- return;
- }
-
- tst_resm(TPASS, "basic semaphore values are okay");
+ SAFE_SEMCTL(sem_id, PSEMS, IPC_RMID);
}
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
+ sem_key = GETIPCKEY();
}
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
- /* if it exists, remove the semaphore resouce */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
+ if (sem_id != -1)
+ SAFE_SEMCTL(sem_id, PSEMS, IPC_RMID);
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_semget,
+};
diff --git a/testcases/kernel/syscalls/ipc/semget/semget02.c b/testcases/kernel/syscalls/ipc/semget/semget02.c
index 4124514c2..4273c84c7 100644
--- a/testcases/kernel/syscalls/ipc/semget/semget02.c
+++ b/testcases/kernel/syscalls/ipc/semget/semget02.c
@@ -1,165 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * NAME
- * semget02.c
+/*\
+ * [Description]
*
- * DESCRIPTION
- * semget02 - test for EACCES and EEXIST errors
+ * This basic error handing of the semget syscall.
*
- * ALGORITHM
- * create a semaphore set without read or alter permissions
- * loop if that option was specified
- * call semget() using two different invalid cases
- * check the errno value
- * issue a PASS message if we get EACCES or EEXIST
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- * none
+ * - EACCES - a semaphore set exists for key, but the calling process does not
+ * have permission to access the set
+ * - EEXIST - a semaphore set already exists for key and IPC_CREAT | IPC_EXCL
+ * is given
+ * - ENOENT - No semaphore set exists for key and semflg did not specify
+ * IPC_CREAT
+ * - EINVAL - nsems is less than 0 or greater than the limit on the number of
+ * semaphores per semaphore set(SEMMSL)
+ * - EINVAL - a semaphore set corresponding to key already exists, but nsems is
+ * larger than the number of semaphores in that set
*/
-#include <pwd.h>
-
-#include "ipcsem.h"
-char *TCID = "semget02";
-int TST_TOTAL = 2;
-
-char nobody_uid[] = "nobody";
-struct passwd *ltpuser;
-
-int sem_id_1 = -1;
-
-struct test_case_t {
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+#include "lapi/sem.h"
+
+static int sem_id = -1;
+static key_t semkey, semkey1;
+static struct passwd *pw;
+static struct tcase {
+ int *key;
+ int nsems;
int flags;
- int error;
-} TC[] = {
- /* EACCES - the semaphore has no read or alter permissions */
- {
- SEM_RA, EACCES},
- /* EEXIST - the semaphore id exists and semget() was called with */
- /* IPC_CREAT and IPC_EXCL */
- {
- IPC_CREAT | IPC_EXCL, EEXIST}
+ int exp_err;
+ /*1: nobody expected, 0: root expected */
+ int exp_user;
+} tcases[] = {
+ {&semkey, PSEMS, SEM_RA, EACCES, 1},
+ {&semkey, PSEMS, IPC_CREAT | IPC_EXCL, EEXIST, 0},
+ {&semkey1, PSEMS, SEM_RA, ENOENT, 0},
+ {&semkey1, -1, IPC_CREAT | IPC_EXCL, EINVAL, 0},
+ {&semkey1, SEMMSL + 1, IPC_CREAT | IPC_EXCL, EINVAL, 0},
+ {&semkey, PSEMS + 1, SEM_RA, EINVAL, 0},
};
-int main(int ac, char **av)
+static void verify_semget(struct tcase *tc)
{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup(); /* global setup */
-
- /* The following loop checks looping state if -i option given */
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++) {
- /* use the TEST macro to make the call */
-
- TEST(semget(semkey, PSEMS, TC[i].flags));
-
- if (TEST_RETURN != -1) {
- sem_id_1 = TEST_RETURN;
- tst_resm(TFAIL, "call succeeded");
- continue;
- }
+ TST_EXP_FAIL2(semget(*tc->key, tc->nsems, tc->flags), tc->exp_err,
+ "semget(%i, %i, %i)", *tc->key, tc->nsems, tc->flags);
+}
- if (TEST_ERRNO == TC[i].error) {
- tst_resm(TPASS, "expected failure - errno "
- "= %d : %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_resm(TFAIL, "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- }
+static void do_test(unsigned int n)
+{
+ pid_t pid;
+ struct tcase *tc = &tcases[n];
+
+ if (tc->exp_user == 0) {
+ verify_semget(tc);
+ } else {
+ pid = SAFE_FORK();
+ if (pid) {
+ tst_reap_children();
+ } else {
+ SAFE_SETUID(pw->pw_uid);
+ verify_semget(tc);
+ exit(0);
}
}
-
- cleanup();
-
- tst_exit();
}
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
{
- tst_require_root();
-
- /* Switch to nobody user for correct error code collection */
- ltpuser = getpwnam(nobody_uid);
- if (seteuid(ltpuser->pw_uid) == -1) {
- tst_resm(TINFO, "setreuid failed to "
- "to set the effective uid to %d", ltpuser->pw_uid);
- perror("setreuid");
- }
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ semkey = GETIPCKEY();
+ semkey1 = GETIPCKEY();
- TEST_PAUSE;
+ sem_id = SAFE_SEMGET(semkey, PSEMS, IPC_CREAT | IPC_EXCL);
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
-
- /* create a semaphore set without read or alter permissions */
- if ((sem_id_1 = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL)) == -1) {
- tst_brkm(TBROK, cleanup, "couldn't create semaphore in setup");
- }
+ pw = SAFE_GETPWNAM("nobody");
}
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
- /* if it exists, remove the semaphore resource */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
+ if (sem_id != -1)
+ SAFE_SEMCTL(sem_id, PSEMS, IPC_RMID);
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .forks_child = 1,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = do_test,
+};
diff --git a/testcases/kernel/syscalls/ipc/semget/semget03.c b/testcases/kernel/syscalls/ipc/semget/semget03.c
deleted file mode 100644
index 995b4bd3a..000000000
--- a/testcases/kernel/syscalls/ipc/semget/semget03.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- * semget03.c
- *
- * DESCRIPTION
- * semget03 - test for ENOENT error
- *
- * ALGORITHM
- * loop if that option was specified
- * call semget() with a valid key but with no associated semaphore set
- * and IPC_CREAT is not asserted
- * check the errno value
- * issue a PASS message if we get ENOENT
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- * none
- */
-
-#include "ipcsem.h"
-
-char *TCID = "semget03";
-int TST_TOTAL = 1;
-
-int sem_id_1 = -1;
-
-int main(int ac, char **av)
-{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup(); /* global setup */
-
- /* The following loop checks looping state if -i option given */
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- /* use the TEST macro to make the call */
-
- TEST(semget(semkey, PSEMS, SEM_RA));
-
- if (TEST_RETURN != -1) {
- sem_id_1 = TEST_RETURN;
- tst_resm(TFAIL, "call succeeded when error expected");
- continue;
- }
-
- switch (TEST_ERRNO) {
- case ENOENT:
- tst_resm(TPASS, "expected failure - errno "
- "= %d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- default:
- tst_resm(TFAIL, "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- }
- }
-
- cleanup();
-
- tst_exit();
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
-{
- /* if it exists, remove the semaphore resource */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
-}
diff --git a/testcases/kernel/syscalls/ipc/semget/semget05.c b/testcases/kernel/syscalls/ipc/semget/semget05.c
index f801cb8ed..dd9a6285d 100644
--- a/testcases/kernel/syscalls/ipc/semget/semget05.c
+++ b/testcases/kernel/syscalls/ipc/semget/semget05.c
@@ -1,152 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * NAME
- * semget05.c
- *
- * DESCRIPTION
- * semget05 - test for ENOSPC error
+/*\
+ * [Description]
*
- * ALGORITHM
- * create semaphore sets in a loop until the system limit is reached
- * loop if that option was specified
- * attempt to create yet another semaphore set
- * check the errno value
- * issue a PASS message if we get ENOSPC
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
+ * Test for ENOSPC error.
*
- * USAGE: <for command-line>
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
- * 07/2006 - Changes By Michael Reed
- * - Changed the value of MAXIDS for the specific machine by reading
- * the system limit for SEMMNI - The maximum number of sempahore sets
- * 03/2008 - Matthieu Fertré (mfertre@irisa.fr)
- * - Fix concurrency issue. Create private semaphores to
- * avoid conflict with concurrent processes.
- *
- * RESTRICTIONS
- * none
- */
-
-#include "ipcsem.h"
-
-char *TCID = "semget05";
-int TST_TOTAL = 1;
-
-/*
- * The MAXIDS value is somewhat arbitrary and may need to be increased
- * depending on the system being tested.
+ * ENOSPC - a semaphore set exceed the maximum number of semaphore sets(SEMMNI)
*/
-int MAXIDS = 2048;
-
-int *sem_id_arr = NULL;
-int num_sems = 0; /* count the semaphores created */
-
-int main(int ac, char **av)
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include "lapi/sem.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+
+static int *sem_id_arr;
+static int maxsems, array_cnt, used_cnt;
+static key_t semkey;
+
+static void verify_semget(void)
{
- int lc;
- FILE *fp;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- /* Set the MAXIDS for the specific machine by reading the system limit
- * for SEMMNI - The maximum number of sempahore sets
- */
- fp = fopen("/proc/sys/kernel/sem", "r");
- if (fp != NULL) {
- int getmaxid;
- if (fscanf(fp, "%*d %*d %*d %d", &getmaxid) == 1)
- MAXIDS = getmaxid + 1;
- fclose(fp);
- }
-
- sem_id_arr = malloc(sizeof(int) * MAXIDS);
- if (sem_id_arr == NULL)
- tst_brkm(TBROK, cleanup, "malloc failed");
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
-
- TEST(semget(IPC_PRIVATE, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA));
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "call succeeded when error expected");
- continue;
- }
-
- switch (TEST_ERRNO) {
- case ENOSPC:
- tst_resm(TPASS, "expected failure - errno "
- "= %d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- default:
- tst_resm(TFAIL, "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- }
- }
-
- cleanup();
-
- tst_exit();
+ TST_EXP_FAIL2(semget(semkey + maxsems, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA),
+ ENOSPC, "semget(%i, %i, %i)", semkey + maxsems, PSEMS,
+ IPC_CREAT | IPC_EXCL | SEM_RA);
}
-void setup(void)
+static void setup(void)
{
- int sem_q;
+ int res, num;
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ semkey = GETIPCKEY();
+ used_cnt = GET_USED_ARRAYS();
+ tst_res(TINFO, "Current environment %d semaphore arrays are already in use",
+ used_cnt);
+ SAFE_FILE_SCANF("/proc/sys/kernel/sem", "%*d %*d %*d %d", &maxsems);
- TEST_PAUSE;
+ /* Prevent timeout due to high semaphore array limit */
+ tst_set_max_runtime(maxsems / 200);
- tst_tmpdir();
-
- while ((sem_q = semget(IPC_PRIVATE, PSEMS, IPC_CREAT | IPC_EXCL)) != -1) {
- sem_id_arr[num_sems++] = sem_q;
- if (num_sems == MAXIDS) {
- tst_brkm(TBROK, cleanup, "The maximum number of "
- "semaphore ID's has been\n\t reached. Please "
- "increase the MAXIDS value in the test.");
- }
- }
+ sem_id_arr = SAFE_MALLOC((maxsems - used_cnt) * sizeof(int));
+ for (num = 0; num < maxsems - used_cnt; num++) {
+ res = semget(semkey + num, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA);
+ if (res == -1)
+ tst_brk(TBROK | TERRNO, "semget failed unexpectedly");
- if (errno != ENOSPC) {
- tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup"
- " - errno = %d : %s", errno, strerror(errno));
+ sem_id_arr[array_cnt++] = res;
}
+ tst_res(TINFO, "The maximum number of semaphore arrays (%d) has been reached",
+ maxsems);
}
-void cleanup(void)
+static void cleanup(void)
{
- int i;
+ int num;
- for (i = 0; i < num_sems; i++) {
- rm_sema(sem_id_arr[i]);
- }
+ if (!sem_id_arr)
+ return;
+
+ for (num = 0; num < array_cnt; num++)
+ SAFE_SEMCTL(sem_id_arr[num], PSEMS, IPC_RMID);
free(sem_id_arr);
- tst_rmdir();
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_semget,
+ .save_restore = (const struct tst_path_val[]){
+ {"/proc/sys/kernel/sem", NULL,
+ TST_SR_TCONF_MISSING | TST_SR_SKIP_RO},
+ {}
+ }
+};
diff --git a/testcases/kernel/syscalls/ipc/semget/semget06.c b/testcases/kernel/syscalls/ipc/semget/semget06.c
deleted file mode 100644
index 52297c010..000000000
--- a/testcases/kernel/syscalls/ipc/semget/semget06.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- * semget06.c
- *
- * DESCRIPTION
- * semget06 - test for EINVAL error
- *
- * ALGORITHM
- * loop if that option was specified
- * call semget() using two different invalid cases - too many and too
- * few primitive semaphores
- * check the errno value
- * issue a PASS message if we get EINVAL
- * otherwise, the tests fails
- * issue a FAIL message
- * call cleanup
- *
- * USAGE: <for command-line>
- * semget06 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- * none
- */
-
-#include "ipcsem.h"
-
-char *TCID = "semget06";
-int TST_TOTAL = 2;
-
-#define LARGENUM 1024 * 32
-#define SMALLNUM -1
-
-int sem_id_1 = -1;
-
-int num_sems[] = { LARGENUM, SMALLNUM };
-
-int main(int ac, char **av)
-{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup(); /* global setup */
-
- /* The following loop checks looping state if -i option given */
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- /* loop through the test cases */
-
- for (i = 0; i < TST_TOTAL; i++) {
- TEST(semget(semkey, num_sems[i],
- IPC_CREAT | IPC_EXCL | SEM_RA));
-
- if (TEST_RETURN != -1) {
- sem_id_1 = TEST_RETURN;
- tst_resm(TFAIL, "call succeeded");
- continue;
- }
-
- switch (TEST_ERRNO) {
- case EINVAL:
- tst_resm(TPASS, "expected failure - errno "
- "= %d : %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- break;
- default:
- tst_resm(TFAIL, "unexpected error - %d : %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- }
- }
- }
-
- cleanup();
-
- tst_exit();
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /*
- * Create a temporary directory and cd into it.
- * This helps to ensure that a unique msgkey is created.
- * See libs/libltpipc/libipc.c for more information.
- */
- tst_tmpdir();
-
- /* get an IPC resource key */
- semkey = getipckey();
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * or premature exit.
- */
-void cleanup(void)
-{
- /* if it exists, remove the semaphore resource */
- rm_sema(sem_id_1);
-
- tst_rmdir();
-
-}
diff --git a/testcases/kernel/syscalls/ipc/semop/.gitignore b/testcases/kernel/syscalls/ipc/semop/.gitignore
index bb57f08af..cc67b1862 100644
--- a/testcases/kernel/syscalls/ipc/semop/.gitignore
+++ b/testcases/kernel/syscalls/ipc/semop/.gitignore
@@ -1,3 +1,5 @@
/semop01
/semop02
/semop03
+/semop04
+/semop05
diff --git a/testcases/kernel/syscalls/ipc/semop/Makefile b/testcases/kernel/syscalls/ipc/semop/Makefile
index 6b2b26d05..43afffb3f 100644
--- a/testcases/kernel/syscalls/ipc/semop/Makefile
+++ b/testcases/kernel/syscalls/ipc/semop/Makefile
@@ -7,6 +7,9 @@ LTPLIBS = ltpnewipc
include $(top_srcdir)/include/mk/testcases.mk
-LTPLDLIBS = -lltpnewipc
+semop01: LTPLDLIBS = -lltpnewipc
+semop02: LTPLDLIBS = -lltpnewipc
+semop03: LTPLDLIBS = -lltpnewipc
+semop05: LDLIBS += -lpthread
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/semop/semop04.c b/testcases/kernel/syscalls/ipc/semop/semop04.c
new file mode 100644
index 000000000..1f49e7740
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/semop/semop04.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (C) 2003-2023 Linux Test Project, Inc.
+ * Author: 2001 Paul Larson <plars@us.ibm.com>
+ * Modified: 2001 Manoj Iyer <manjo@ausin.ibm.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Creates a semaphore and two processes. The processes
+ * each go through a loop where they semdown, delay for a
+ * random amount of time, and semup, so they will almost
+ * always be fighting for control of the semaphore.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include "lapi/sem.h"
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+
+#define LOOPS 1000
+#define SEED 123
+
+static void semup(int semid)
+{
+ struct sembuf semops;
+
+ semops.sem_num = 0;
+ semops.sem_op = 1;
+ semops.sem_flg = SEM_UNDO;
+
+ SAFE_SEMOP(semid, &semops, 1);
+}
+
+static void semdown(int semid)
+{
+ struct sembuf semops;
+
+ semops.sem_num = 0;
+ semops.sem_op = -1;
+ semops.sem_flg = SEM_UNDO;
+
+ SAFE_SEMOP(semid, &semops, 1);
+}
+
+static void mainloop(int semid)
+{
+ int i;
+
+ for (i = 0; i < LOOPS; i++) {
+ semdown(semid);
+ usleep(1 + ((100.0 * rand()) / RAND_MAX));
+ semup(semid);
+ }
+}
+
+static void run(void)
+{
+ int semid;
+ union semun semunion;
+ pid_t pid;
+
+ /* set up the semaphore */
+ semid = SAFE_SEMGET((key_t) 9142, 1, 0666 | IPC_CREAT);
+
+ semunion.val = 1;
+
+ SAFE_SEMCTL(semid, 0, SETVAL, semunion);
+
+ tst_res(TINFO, "srand seed is %d", SEED);
+ srand(SEED);
+
+ pid = SAFE_FORK();
+
+ if (pid) {
+ mainloop(semid);
+ tst_reap_children();
+ TST_EXP_POSITIVE(semctl(semid, 0, IPC_RMID, semunion));
+ } else {
+ mainloop(semid);
+ }
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/ipc/semaphore/sem02.c b/testcases/kernel/syscalls/ipc/semop/semop05.c
index 34b714bf0..34b714bf0 100644
--- a/testcases/kernel/ipc/semaphore/sem02.c
+++ b/testcases/kernel/syscalls/ipc/semop/semop05.c
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
index 3788e711f..8168803a5 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
@@ -11,17 +11,17 @@
*
* Test for ENOENT, EEXIST, EINVAL, EACCES, EPERM errors.
*
- * ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
- * EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
- * EINVAL - A new segment was to be created and size is less than SHMMIN or
- * greater than SHMMAX. Or a segment for the given key exists, but size is
- * gran eater than the size of that segment.
- * EACCES - The user does not have permission to access the shared memory segment.
- * EPERM - The SHM_HUGETLB flag was specified, but the caller was not privileged
- * (did not have the CAP_IPC_LOCK capability) and is not a member of the
- * sysctl_hugetlb_shm_group group.
- * ENOMEM - The SHM_HUGETLB flag was specified, the caller was privileged but not
- * have enough hugepage memory space.
+ * - ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
+ * - EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
+ * - EINVAL - A new segment was to be created and size is less than SHMMIN or
+ * greater than SHMMAX. Or a segment for the given key exists, but size is
+ * gran eater than the size of that segment.
+ * - EACCES - The user does not have permission to access the shared memory segment.
+ * - EPERM - The SHM_HUGETLB flag was specified, but the caller was not
+ * privileged (did not have the CAP_IPC_LOCK capability) and is not a member
+ * of the sysctl_hugetlb_shm_group group.
+ * - ENOMEM - The SHM_HUGETLB flag was specified, the caller was privileged but
+ * not have enough hugepage memory space.
*/
#include <errno.h>
@@ -56,7 +56,7 @@ static struct tcase {
{&shmkey1, SHM_SIZE, IPC_EXCL, 0, 0, ENOENT},
{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, 0, EEXIST},
{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, 0, EINVAL},
- {&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, 0, EINVAL},
+ {&shmkey1, 8192 + 1, IPC_CREAT | IPC_EXCL, 0, 0, EINVAL},
{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, 0, EINVAL},
{&shmkey, SHM_SIZE, SHM_RD, 1, 0, EACCES},
{&shmkey1, SHM_SIZE, IPC_CREAT | SHM_HUGETLB, 0, 1, EPERM},
@@ -149,4 +149,8 @@ static struct tst_test test = {
.test = do_test,
.tcnt = ARRAY_SIZE(tcases),
.hugepages = {TST_NO_HUGEPAGES},
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/kernel/shmmax", "8192", TST_SR_TCONF_MISSING | TST_SR_TBROK_RO},
+ {}
+ },
};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl02.c b/testcases/kernel/syscalls/keyctl/keyctl02.c
index 572f34b16..35cc2838d 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl02.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl02.c
@@ -144,6 +144,7 @@ static struct tst_test test = {
.test_all = do_test,
.tags = (const struct tst_tag[]) {
{"linux-git", "b4a1b4f5047e"},
+ {"CVE", "2015-7550"},
{}
}
};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl07.c b/testcases/kernel/syscalls/keyctl/keyctl07.c
index 875ef0bb8..d9e20db5f 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl07.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl07.c
@@ -104,7 +104,7 @@ static struct tst_test test = {
.test_all = do_test,
.forks_child = 1,
.tags = (const struct tst_tag[]) {
- {"CVE", "2017-12912"},
+ {"CVE", "2017-12192"},
{"linux-git", "37863c43b2c6"},
{}
}
diff --git a/testcases/kernel/syscalls/madvise/.gitignore b/testcases/kernel/syscalls/madvise/.gitignore
index f4bfdfefe..722ac3c34 100644
--- a/testcases/kernel/syscalls/madvise/.gitignore
+++ b/testcases/kernel/syscalls/madvise/.gitignore
@@ -7,3 +7,4 @@
/madvise08
/madvise09
/madvise10
+/madvise11
diff --git a/testcases/kernel/syscalls/madvise/Makefile b/testcases/kernel/syscalls/madvise/Makefile
index 044619fb8..78613df11 100644
--- a/testcases/kernel/syscalls/madvise/Makefile
+++ b/testcases/kernel/syscalls/madvise/Makefile
@@ -6,3 +6,5 @@ top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+madvise11: CFLAGS += -pthread
diff --git a/testcases/kernel/syscalls/madvise/madvise01.c b/testcases/kernel/syscalls/madvise/madvise01.c
index 2262bf12d..884c59b0b 100644
--- a/testcases/kernel/syscalls/madvise/madvise01.c
+++ b/testcases/kernel/syscalls/madvise/madvise01.c
@@ -11,7 +11,6 @@
*/
#include <sys/types.h>
-#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <errno.h>
diff --git a/testcases/kernel/syscalls/madvise/madvise02.c b/testcases/kernel/syscalls/madvise/madvise02.c
index 858d67ae2..90c0431c5 100644
--- a/testcases/kernel/syscalls/madvise/madvise02.c
+++ b/testcases/kernel/syscalls/madvise/madvise02.c
@@ -30,7 +30,6 @@
*/
#include <sys/types.h>
-#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
diff --git a/testcases/kernel/syscalls/madvise/madvise06.c b/testcases/kernel/syscalls/madvise/madvise06.c
index c7967ae6f..be22318ea 100644
--- a/testcases/kernel/syscalls/madvise/madvise06.c
+++ b/testcases/kernel/syscalls/madvise/madvise06.c
@@ -198,7 +198,7 @@ static void test_advice_willneed(void)
meminfo_diag("After madvise");
res = swapcached > swapcached_start + PASS_THRESHOLD_KB;
- tst_res(res ? TPASS : TFAIL,
+ tst_res(res ? TPASS : TINFO,
"%s than %ld Kb were moved to the swap cache",
res ? "more" : "less", PASS_THRESHOLD_KB);
@@ -226,10 +226,15 @@ static void test_advice_willneed(void)
meminfo_diag("After page access");
res = page_fault_num_2 - page_fault_num_1;
- tst_res(res == 0 ? TPASS : TFAIL,
+ tst_res(res == 0 ? TPASS : TINFO,
"%d pages were faulted out of 3 max", res);
SAFE_MUNMAP(target, CHUNK_SZ);
+
+ if (tst_taint_check())
+ tst_res(TFAIL, "Kernel tainted");
+ else
+ tst_res(TPASS, "No kernel taints");
}
static struct tst_test test = {
@@ -237,6 +242,7 @@ static struct tst_test test = {
.setup = setup,
.needs_tmpdir = 1,
.needs_root = 1,
+ .taint_check = TST_TAINT_W | TST_TAINT_D,
.save_restore = (const struct tst_path_val[]) {
{"/proc/sys/vm/swappiness", NULL,
TST_SR_SKIP_MISSING | TST_SR_TCONF_RO},
diff --git a/testcases/kernel/syscalls/madvise/madvise11.c b/testcases/kernel/syscalls/madvise/madvise11.c
new file mode 100644
index 000000000..7a12abf20
--- /dev/null
+++ b/testcases/kernel/syscalls/madvise/madvise11.c
@@ -0,0 +1,442 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates.
+ */
+
+/*\
+ * [Description]
+ *
+ * Stress a possible race condition between memory pages allocation
+ * and soft-offline of unrelated pages as explained in the commit:
+ * d4ae9916ea29 (mm: soft-offline: close the race against page allocation)
+ *
+ * Control that soft-offlined pages get correctly replaced: with the
+ * same content and without SIGBUS generation when accessed.
+ */
+
+#include <errno.h>
+#include <mntent.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/klog.h>
+
+#include "tst_test.h"
+#include "tst_safe_pthread.h"
+#include "tst_safe_stdio.h"
+#include "lapi/mmap.h"
+
+#define NUM_LOOPS 5
+#define NUM_PAGES 32
+#define NUM_PAGES_OFFSET 5
+
+/* Needed module to online back memory pages */
+#define HW_MODULE "hwpoison_inject"
+
+static pthread_t *thread_ids;
+static int number_threads;
+static int run_iterations;
+static int maximum_pfns;
+
+static volatile int sigbus_received;
+static pthread_cond_t sigbus_received_cv;
+static pthread_mutex_t sigbus_received_mtx = PTHREAD_MUTEX_INITIALIZER;
+
+static long pagesize;
+static char beginning_tag[BUFSIZ];
+static int hwpoison_probe;
+
+static void my_yield(void)
+{
+ static const struct timespec t0 = { 0, 0 };
+
+ nanosleep(&t0, NULL);
+}
+
+/* a SIGBUS received is a confirmation of test failure */
+static void sigbus_handler(int signum LTP_ATTRIBUTE_UNUSED)
+{
+ pthread_mutex_lock(&sigbus_received_mtx);
+ sigbus_received++;
+ pthread_cond_signal(&sigbus_received_cv);
+ pthread_mutex_unlock(&sigbus_received_mtx);
+ pause();
+}
+
+static void *sigbus_monitor(void *arg LTP_ATTRIBUTE_UNUSED)
+{
+ pthread_mutex_lock(&sigbus_received_mtx);
+ while (!sigbus_received)
+ pthread_cond_wait(&sigbus_received_cv, &sigbus_received_mtx);
+ pthread_mutex_unlock(&sigbus_received_mtx);
+ tst_res(TFAIL, "SIGBUS Received");
+ exit(1);
+}
+
+/*
+ * Allocate a page and write a sentinel value into it.
+ */
+static void *allocate_write(int sentinel)
+{
+ void *p;
+ int *s;
+
+ p = SAFE_MMAP(NULL, pagesize, PROT_READ|PROT_WRITE,
+ MAP_SHARED|MAP_ANONYMOUS, -1, 0);
+ s = (int *)p;
+ *s = sentinel;
+ return p;
+}
+
+/*
+ * Verify and unmap the given page.
+ */
+static int verif_unmap(void *page, int sentinel)
+{
+ int *s = (int *)page;
+
+ if (*s != sentinel) {
+ tst_res(TFAIL, "pid[%d]: fail: bad sentinel value seen: %d expected: %d\n", getpid(), *s, sentinel);
+ return 1;
+ }
+
+ return SAFE_MUNMAP(page, pagesize);
+}
+
+/*
+ * allocate_offline() - Allocate and offline test called per-thread
+ *
+ * This function does the allocation and offline by mmapping an
+ * anonymous page and offlining it.
+ */
+static int allocate_offline(int tnum)
+{
+ int loop;
+
+ for (loop = 0; loop < NUM_LOOPS; loop++) {
+ long *ptrs[NUM_PAGES];
+ int num_alloc;
+ int i;
+
+ for (num_alloc = 0; num_alloc < NUM_PAGES; num_alloc++) {
+
+ ptrs[num_alloc] = allocate_write((tnum << NUM_PAGES_OFFSET) | num_alloc);
+ if (ptrs[num_alloc] == NULL)
+ return -1;
+
+ if (madvise(ptrs[num_alloc], pagesize, MADV_SOFT_OFFLINE) == -1) {
+ if (errno != EINVAL)
+ tst_res(TFAIL | TERRNO, "madvise failed");
+ if (errno == EINVAL)
+ tst_res(TCONF, "madvise() didn't support MADV_SOFT_OFFLINE");
+ return errno;
+ }
+ }
+
+ for (i = 0; i < num_alloc; i++) {
+ if (verif_unmap(ptrs[i], (tnum << NUM_PAGES_OFFSET) | i) != 0)
+ return 1;
+ }
+
+ my_yield();
+ if (!tst_remaining_runtime()) {
+ tst_res(TINFO, "Thread [%d]: Test runtime is over, exiting", tnum);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void *alloc_mem(void *threadnum)
+{
+ int err;
+ int tnum = (int)(uintptr_t)threadnum;
+
+ /* waiting for other threads starting */
+ TST_CHECKPOINT_WAIT(0);
+
+ err = allocate_offline(tnum);
+ tst_res(TINFO,
+ "Thread [%d] returned %d, %s.", tnum, err, (err ? "failed" : "succeeded"));
+ return (void *)(uintptr_t) (err ? -1 : 0);
+}
+
+static void stress_alloc_offl(void)
+{
+ int thread_index;
+ int thread_failure = 0;
+ pthread_t sigbus_monitor_t;
+
+ run_iterations++;
+
+ SAFE_PTHREAD_CREATE(&sigbus_monitor_t, NULL, sigbus_monitor, NULL);
+ pthread_detach(sigbus_monitor_t);
+
+ for (thread_index = 0; thread_index < number_threads; thread_index++) {
+ SAFE_PTHREAD_CREATE(&thread_ids[thread_index], NULL, alloc_mem,
+ (void *)(uintptr_t)thread_index);
+ }
+
+ TST_CHECKPOINT_WAKE2(0, number_threads);
+
+ for (thread_index = 0; thread_index < number_threads; thread_index++) {
+ void *status;
+
+ SAFE_PTHREAD_JOIN(thread_ids[thread_index], &status);
+ if ((intptr_t)status != 0) {
+ tst_res(TFAIL, "thread [%d] - exited with errors",
+ thread_index);
+ thread_failure++;
+ }
+ }
+
+ if (thread_failure == 0)
+ tst_res(TPASS, "soft-offline / mmap race still clean");
+}
+
+/*
+ * ------------
+ * Cleanup code:
+ * The idea is to retrieve all the pfn numbers that have been soft-offined
+ * (generating a "Soft offlining pfn 0x..." message in the kernel ring buffer)
+ * by the current test (since a "beginning_tag" message we write when starting).
+ * And to put these pages back online by writing the pfn number to the
+ * <debugfs>/hwpoison/unpoison-pfn special file.
+ * ------------
+ */
+#define OFFLINE_PATTERN "Soft offlining pfn 0x"
+#define OFFLINE_PATTERN_LEN sizeof(OFFLINE_PATTERN)
+
+/* return the pfn if the kmsg msg is a soft-offline indication*/
+static unsigned long parse_kmsg_soft_offlined_pfn(char *line, ssize_t len)
+{
+ char *pos;
+ unsigned long addr = 0UL;
+
+ pos = strstr(line, OFFLINE_PATTERN);
+ if (pos == NULL)
+ return 0UL;
+
+ pos += OFFLINE_PATTERN_LEN-1;
+ if (pos > (line + len))
+ return 0UL;
+
+ addr = strtoul(pos, NULL, 16);
+ if ((addr == ULONG_MAX) && (errno == ERANGE))
+ return 0UL;
+
+ return addr;
+}
+
+/* return the pfns seen in kernel message log */
+static int populate_from_klog(char *begin_tag, unsigned long *pfns, int max)
+{
+ int found = 0, fd, beginning_tag_found = 0;
+ ssize_t sz;
+ unsigned long pfn;
+ char buf[BUFSIZ];
+
+ fd = SAFE_OPEN("/dev/kmsg", O_RDONLY|O_NONBLOCK);
+
+ while (found < max) {
+ sz = read(fd, buf, sizeof(buf));
+ /* kmsg returns EPIPE if record was modified while reading */
+ if (sz < 0 && errno == EPIPE)
+ continue;
+ if (sz <= 0)
+ break;
+ if (!beginning_tag_found) {
+ if (strstr(buf, begin_tag))
+ beginning_tag_found = 1;
+ continue;
+ }
+ pfn = parse_kmsg_soft_offlined_pfn(buf, sz);
+ if (pfn)
+ pfns[found++] = pfn;
+ }
+ SAFE_CLOSE(fd);
+ return found;
+}
+
+/*
+ * Read the given file to search for the key.
+ * Return 1 if the key is found.
+ */
+static int find_in_file(char *path, char *key)
+{
+ char line[4096];
+ int found = 0;
+ FILE *file = SAFE_FOPEN(path, "r");
+
+ while (fgets(line, sizeof(line), file)) {
+ if (strstr(line, key)) {
+ found = 1;
+ break;
+ }
+ }
+ SAFE_FCLOSE(file);
+ return found;
+}
+
+static void unpoison_this_pfn(unsigned long pfn, int fd)
+{
+ char pfn_str[19];
+
+ snprintf(pfn_str, sizeof(pfn_str), "0x%lx", pfn);
+ SAFE_WRITE(0, fd, pfn_str, strlen(pfn_str));
+}
+
+/* Find and open the <debugfs>/hwpoison/unpoison-pfn special file */
+static int open_unpoison_pfn(void)
+{
+ char *added_file_path = "/hwpoison/unpoison-pfn";
+ const char *const cmd_modprobe[] = {"modprobe", HW_MODULE, NULL};
+ char debugfs_fp[4096];
+ struct mntent *mnt;
+ FILE *mntf;
+
+ if (!find_in_file("/proc/modules", HW_MODULE) && tst_check_builtin_driver(HW_MODULE))
+ hwpoison_probe = 1;
+
+ /* probe hwpoison only if it isn't already there */
+ if (hwpoison_probe)
+ SAFE_CMD(cmd_modprobe, NULL, NULL);
+
+ /* debugfs mount point */
+ mntf = setmntent("/proc/mounts", "r");
+ if (!mntf) {
+ tst_brk(TBROK | TERRNO, "Can't open /proc/mounts");
+ return -1;
+ }
+ while ((mnt = getmntent(mntf)) != NULL) {
+ if (strcmp(mnt->mnt_type, "debugfs") == 0) {
+ strcpy(debugfs_fp, mnt->mnt_dir);
+ strcat(debugfs_fp, added_file_path);
+ break;
+ }
+ }
+ endmntent(mntf);
+ if (!mnt)
+ return -1;
+
+ TEST(open(debugfs_fp, O_WRONLY));
+
+ if (TST_RET == -1 && TST_ERR == EPERM && tst_lockdown_enabled() > 0) {
+ tst_res(TINFO,
+ "Cannot restore soft-offlined memory due to lockdown");
+ return TST_RET;
+ }
+
+ if (TST_RET == -1) {
+ tst_brk(TBROK | TTERRNO, "open(%s) failed", debugfs_fp);
+ } else if (TST_RET < 0) {
+ tst_brk(TBROK | TTERRNO, "Invalid open() return value %ld",
+ TST_RET);
+ }
+
+ return TST_RET;
+}
+
+/*
+ * Get all the Offlined PFNs indicated in the dmesg output
+ * starting after the given beginning tag, and request a debugfs
+ * hwpoison/unpoison-pfn for each of them.
+ */
+static void unpoison_pfn(char *begin_tag)
+{
+ unsigned long *pfns;
+ const char *const cmd_rmmod[] = {"rmmod", HW_MODULE, NULL};
+ int found_pfns, fd;
+
+ pfns = SAFE_MALLOC(sizeof(pfns) * maximum_pfns * run_iterations);
+
+ fd = open_unpoison_pfn();
+ if (fd >= 0) {
+ found_pfns = populate_from_klog(begin_tag, pfns, maximum_pfns * run_iterations);
+
+ tst_res(TINFO, "Restore %d Soft-offlined pages", found_pfns);
+ /* unpoison in reverse order */
+ while (found_pfns-- > 0)
+ unpoison_this_pfn(pfns[found_pfns], fd);
+
+ SAFE_CLOSE(fd);
+ }
+ /* remove hwpoison only if we probed it */
+ if (hwpoison_probe)
+ SAFE_CMD(cmd_rmmod, NULL, NULL);
+}
+
+/*
+ * Create and write a beginning tag to the kernel buffer to be used on cleanup
+ * when trying to restore the soft-offlined pages of our test run.
+ */
+static void write_beginning_tag_to_kmsg(void)
+{
+ int fd;
+
+ fd = SAFE_OPEN("/dev/kmsg", O_WRONLY);
+ snprintf(beginning_tag, sizeof(beginning_tag),
+ "Soft-offlining pages test starting (pid: %ld)",
+ (long)getpid());
+ SAFE_WRITE(1, fd, beginning_tag, strlen(beginning_tag));
+ SAFE_CLOSE(fd);
+}
+
+static void setup(void)
+{
+ struct sigaction my_sigaction;
+
+ number_threads = (int)sysconf(_SC_NPROCESSORS_ONLN) * 2;
+ if (number_threads <= 1)
+ number_threads = 2;
+ else if (number_threads > 5)
+ number_threads = 5;
+
+ maximum_pfns = number_threads * NUM_LOOPS * NUM_PAGES;
+ thread_ids = SAFE_MALLOC(sizeof(pthread_t) * number_threads);
+ pagesize = sysconf(_SC_PAGESIZE);
+
+ /* SIGBUS is the main failure criteria */
+ my_sigaction.sa_handler = sigbus_handler;
+ if (sigaction(SIGBUS, &my_sigaction, NULL) == -1)
+ tst_res(TFAIL | TERRNO, "Signal handler attach failed");
+
+ write_beginning_tag_to_kmsg();
+ tst_res(TINFO, "Spawning %d threads, with a total of %d memory pages",
+ number_threads, maximum_pfns);
+}
+
+static void cleanup(void)
+{
+ unpoison_pfn(beginning_tag);
+}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .needs_drivers = (const char *const []) {
+ HW_MODULE,
+ NULL
+ },
+ .needs_cmds = (const char *[]) {
+ "modprobe",
+ "rmmod",
+ NULL
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_MEMORY_FAILURE=y",
+ NULL
+ },
+ .max_runtime = 30,
+ .needs_checkpoints = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = stress_alloc_offl,
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "d4ae9916ea29"},
+ {}
+ }
+};
diff --git a/testcases/kernel/syscalls/memfd_create/memfd_create02.c b/testcases/kernel/syscalls/memfd_create/memfd_create02.c
index f547e1424..b9ddc0825 100644
--- a/testcases/kernel/syscalls/memfd_create/memfd_create02.c
+++ b/testcases/kernel/syscalls/memfd_create/memfd_create02.c
@@ -13,10 +13,8 @@
#define _GNU_SOURCE
#include <errno.h>
-
-#include <tst_test.h>
-
#include "memfd_create_common.h"
+#include "tst_test.h"
static char buf[2048];
static char term_buf[2048];
diff --git a/testcases/kernel/syscalls/memfd_create/memfd_create04.c b/testcases/kernel/syscalls/memfd_create/memfd_create04.c
index 7b699b218..585f17e16 100644
--- a/testcases/kernel/syscalls/memfd_create/memfd_create04.c
+++ b/testcases/kernel/syscalls/memfd_create/memfd_create04.c
@@ -1,20 +1,23 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) Zilogic Systems Pvt. Ltd., 2018
- * Email: code@zilogic.com
+ * Copyright (c) Zilogic Systems Pvt. Ltd. <code@zilogic.com>, 2018
+ * Copyright (c) Linux Test Project, 2019-2023
*/
-/*
- * Test: Validating memfd_create() with MFD_HUGETLB and MFD_HUGE_x flags.
+/*\
+ * [Description]
+ *
+ * Validating memfd_create() with MFD_HUGETLB and MFD_HUGE_x flags.
*
- * Test cases: Attempt to create files in the hugetlbfs filesystem using
- * different huge page sizes.
+ * Attempt to create files in the hugetlbfs filesystem using different huge page
+ * sizes.
*
- * Test logic: memfd_create() should return non-negative value (fd)
- * if the system supports that particular huge page size.
- * On success, fd is returned.
- * On failure, -1 is returned with ENODEV error.
+ * [Algorithm]
+ *
+ * memfd_create() should return non-negative value (fd) if the system supports
+ * that particular huge page size.
+ * On success, fd is returned. On failure, -1 is returned with ENODEV error.
*/
#define _GNU_SOURCE
@@ -25,8 +28,6 @@
#include <errno.h>
#include <stdio.h>
-#define PATH_HUGEPAGES "/sys/kernel/mm/hugepages"
-
static struct test_flag {
int flag;
char *h_size;
@@ -48,7 +49,7 @@ static void check_hugepage_support(struct test_flag *test_flags)
char pattern[64];
sprintf(pattern, PATH_HUGEPAGES);
- strcat(pattern, "/hugepages-");
+ strcat(pattern, "hugepages-");
strcat(pattern, test_flags->h_size);
if (access(pattern, F_OK))
diff --git a/testcases/kernel/syscalls/mknod/mknod01.c b/testcases/kernel/syscalls/mknod/mknod01.c
index f79e5fa42..7a4d5b43f 100644
--- a/testcases/kernel/syscalls/mknod/mknod01.c
+++ b/testcases/kernel/syscalls/mknod/mknod01.c
@@ -1,123 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- * AUTHOR : William Roske
- * CO-PILOT : Dave Fenner
- *
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ * AUTHOR: William Roske, CO-PILOT: Dave Fenner
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
+ */
+
+/*\
+ * [Description]
*
+ * Verify that mknod(2) successfully creates a filesystem node with
+ * various modes.
*/
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/sysmacros.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "mknod01";
+#include "tst_test.h"
#define PATH "test_node"
-int tcases[] = { /* modes to give nodes created (1 per text case) */
- S_IFREG | 0777, /* ordinary file with mode 0777 */
- S_IFIFO | 0777, /* fifo special with mode 0777 */
- S_IFCHR | 0777, /* character special with mode 0777 */
- S_IFBLK | 0777, /* block special with mode 0777 */
+static int tcases[] = {
+ S_IFREG | 0777,
+ S_IFIFO | 0777,
+ S_IFCHR | 0777,
+ S_IFBLK | 0777,
- S_IFREG | 04700, /* ordinary file with mode 04700 (suid) */
- S_IFREG | 02700, /* ordinary file with mode 02700 (sgid) */
- S_IFREG | 06700, /* ordinary file with mode 06700 (sgid & suid) */
+ S_IFREG | 04700,
+ S_IFREG | 02700,
+ S_IFREG | 06700,
};
-int TST_TOTAL = ARRAY_SIZE(tcases);
-int main(int ac, char **av)
+static void run(unsigned int i)
{
- int lc, i;
- dev_t dev;
-
- tst_parse_opts(ac, av, NULL, NULL);
+ dev_t dev = 0;
- setup();
+ if (S_ISCHR(tcases[i]) || S_ISBLK(tcases[i]))
+ dev = makedev(1, 3);
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++) {
- /*
- * overlayfs doesn't support mknod char device with
- * major 0 and minor 0, which is known as whiteout_dev
- */
- if (S_ISCHR(tcases[i]))
- dev = makedev(1, 3);
- else
- dev = 0;
- TEST(mknod(PATH, tcases[i], dev));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL,
- "mknod(%s, %#o, %lu) failed, errno=%d : %s",
- PATH, tcases[i], dev, TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_resm(TPASS,
- "mknod(%s, %#o, %lu) returned %ld",
- PATH, tcases[i], dev, TEST_RETURN);
- }
-
- SAFE_UNLINK(cleanup, PATH);
- }
-
- }
-
- cleanup();
- tst_exit();
+ TST_EXP_PASS(mknod(PATH, tcases[i], dev),
+ "mknod(PATH, %o, %ld)",
+ tcases[i], dev);
+ SAFE_UNLINK(PATH);
}
-void setup(void)
-{
- tst_require_root();
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- tst_tmpdir();
-}
-
-void cleanup(void)
-{
- tst_rmdir();
-}
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .needs_root = 1,
+ .needs_tmpdir = 1
+};
diff --git a/testcases/kernel/syscalls/mknod/mknod02.c b/testcases/kernel/syscalls/mknod/mknod02.c
index 594473e24..b1885fed1 100644
--- a/testcases/kernel/syscalls/mknod/mknod02.c
+++ b/testcases/kernel/syscalls/mknod/mknod02.c
@@ -1,301 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
* Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test Name: mknod02
- *
- * Test Description:
- * Verify that mknod(2) succeeds when used to create a filesystem
- * node with set group-ID bit set on a directory without set group-ID bit set.
- * The node created should have set group-ID bit set and its gid should be
- * equal to that of its parent directory.
- *
- * Expected Result:
- * mknod() should return value 0 on success and node created should have
- * set group-ID bit set, its gid should be equal to that of its parent
- * directory.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Create temporary directory.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise,
- * Verify the Functionality of system call
- * if successful,
- * Issue Functionality-Pass message.
- * Otherwise,
- * Issue Functionality-Fail message.
- * Cleanup:
- * Print errno log and/or timing stats if options given
- * Delete the temporary directory created.
- *
- * Usage: <for command-line>
- * mknod02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- * This test should be run by 'super-user' (root) only.
+/*\
+ * [Description]
*
+ * Verify that if mknod(2) creates a filesystem node in a directory which
+ * does not have the set-group-ID bit set, new node will not inherit the
+ * group ownership from its parent directory and its group ID will be the
+ * effective group ID of the process.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
#include <pwd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
-#define LTPUSER "nobody"
-#define MODE_RWX S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO
-#define MODE_SGID S_IFIFO | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO
-#define DIR_TEMP "testdir_2"
-#define TNODE "tnode_%d"
+#define MODE_DIR 0777
+#define MODE1 0010777
+#define MODE_SGID 02000
-struct stat buf; /* struct. to hold stat(2) o/p contents */
-struct passwd *user1; /* struct. to hold getpwnam(3) o/p contents */
+#define TEMP_DIR "testdir"
+#define TEMP_NODE "testnode"
-char *TCID = "mknod02";
-int TST_TOTAL = 1;
-char node_name[PATH_MAX]; /* buffer to hold node name created */
+static struct stat buf;
+static struct passwd *user_nobody;
+static gid_t gid_nobody;
-gid_t group1_gid, group2_gid, mygid; /* user and process group id's */
-uid_t save_myuid, user1_uid; /* user and process user id's */
-pid_t mypid; /* process id */
-
-void setup(); /* setup function for the test */
-void cleanup(); /* cleanup function for the test */
-
-int main(int ac, char **av)
+static void setup(void)
{
- int lc;
- int fflag;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Attempt to create a filesystem node with group-id bit set
- * on a directory without group id bit set such that,
- * the node created by mknod(2) should have group-id (sgid)
- * bit set and node's gid should be equal to that of its
- * parent directory.
- */
- TEST(mknod(node_name, MODE_SGID, 0));
-
- /* Check return code from mknod(2) */
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL,
- "mknod(%s, %#o, 0) failed, errno=%d : %s",
- node_name, MODE_SGID, TEST_ERRNO,
- strerror(TEST_ERRNO));
- continue;
- }
- /* Set the functionality flag */
- fflag = 1;
-
- /* Check for node's creation */
- if (stat(node_name, &buf) < 0) {
- tst_resm(TFAIL, "stat() of %s failed, errno:%d",
- node_name, TEST_ERRNO);
-
- /* unset functionality flag */
- fflag = 0;
- }
-
- /* Verify mode permissions of node */
- if (!(buf.st_mode & S_ISGID)) {
- tst_resm(TFAIL, "%s: Incorrect modes, setgid "
- "bit not set", node_name);
- /* unset flag as functionality fails */
- fflag = 0;
- }
-
- /* Verify group ID of node */
- if (buf.st_gid != mygid) {
- tst_resm(TFAIL, "%s: Incorrect group",
- node_name);
- /* unset flag as functionality fails */
- fflag = 0;
- }
- if (fflag) {
- tst_resm(TPASS, "Functionality of mknod(%s, "
- "%#o, 0) successful",
- node_name, MODE_SGID);
- }
-
- /* Remove the node for the next go `round */
- if (unlink(node_name) == -1) {
- tst_resm(TWARN, "unlink(%s) failed, errno:%d %s",
- node_name, errno, strerror(errno));
- }
- }
+ user_nobody = SAFE_GETPWNAM("nobody");
+ gid_nobody = user_nobody->pw_gid;
- /* Change the directory back to temporary directory */
- SAFE_CHDIR(cleanup, "..");
-
- /*
- * Invoke cleanup() to delete the test directories created
- * in the setup() and exit main().
- */
- cleanup();
-
- tst_exit();
+ SAFE_MKDIR(TEMP_DIR, MODE_DIR);
+ SAFE_CHOWN(TEMP_DIR, -1, gid_nobody);
}
-/*
- * setup(void) - performs all ONE TIME setup for this test.
- * Exit the test program on receipt of unexpected signals.
- * Create a temporary directory used to hold test directories created
- * and change the directory to it.
- * Verify that pid of process executing the test is root.
- * Create a test directory on temporary directory and set the ownership
- * of test directory to ltp user and process.
- * Set the effective uid/gid of the process to that of ltp user.
- */
-void setup(void)
+static void run(void)
{
- tst_require_root();
-
- /* Capture unexpected signals */
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /* Make a temp dir and cd to it */
- tst_tmpdir();
-
- /* fix permissions on the tmpdir */
- if (chmod(".", 0711) != 0) {
- tst_brkm(TBROK, cleanup, "chmod() failed");
- }
-
- /* Save the real user id of the current test process */
- save_myuid = getuid();
-
- /* Save the process id of the current test process */
- mypid = getpid();
-
- /* Get the node name to be created in the test */
- sprintf(node_name, TNODE, mypid);
-
- /* Get the uid/gid of ltpuser */
- if ((user1 = getpwnam(LTPUSER)) == NULL) {
- tst_brkm(TBROK | TERRNO, cleanup,
- "Couldn't determine if %s was in /etc/passwd",
- LTPUSER);
- }
- user1_uid = user1->pw_uid;
- group1_gid = user1->pw_gid;
-
- /* Get the effective group id of the test process */
- group2_gid = getegid();
+ SAFE_CHDIR(TEMP_DIR);
+ TST_EXP_PASS(mknod(TEMP_NODE, MODE1, 0), "mknod(%s, %o, 0)", TEMP_NODE, MODE1);
- /*
- * Create a test directory under temporary directory with the
- * specified mode permissions, with uid/gid set to that of guest
- * user and the test process.
- */
- SAFE_MKDIR(cleanup, DIR_TEMP, MODE_RWX);
- SAFE_CHOWN(cleanup, DIR_TEMP, user1_uid, group2_gid);
+ SAFE_STAT(TEMP_NODE, &buf);
+ TST_EXP_EQ_LI(buf.st_gid, 0);
- /*
- * Verify that test directory created with expected permission modes
- * and ownerships.
- */
- SAFE_STAT(cleanup, DIR_TEMP, &buf);
-
- /* Verify modes of test directory */
- if (buf.st_mode & S_ISGID) {
- tst_brkm(TBROK, cleanup,
- "%s: Incorrect modes, setgid bit set", DIR_TEMP);
- }
-
- /* Verify group ID of test directory */
- if (buf.st_gid != group2_gid) {
- tst_brkm(TBROK, cleanup, "%s: Incorrect group", DIR_TEMP);
- }
-
- /*
- * Set the effective group id and user id of the test process
- * to that of guest user.
- */
- SAFE_SETGID(cleanup, group1_gid);
- if (setreuid(-1, user1_uid) < 0) {
- tst_brkm(TBROK, cleanup,
- "Unable to set process uid to that of ltp user");
- }
-
- /* Save the real group ID of the current process */
- mygid = getgid();
-
- /* Change directory to DIR_TEMP */
- SAFE_CHDIR(cleanup, DIR_TEMP);
+ SAFE_UNLINK(TEMP_NODE);
+ SAFE_CHDIR("..");
}
-/*
- * cleanup() - Performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- * Print test timing stats and errno log if test executed with options.
- * Restore the real/effective user id of the process changed during
- * setup().
- * Remove temporary directory and sub-directories/files under it
- * created during setup().
- * Exit the test program with normal exit code.
- */
-void cleanup(void)
-{
-
- /*
- * Restore the effective uid of the process changed in the
- * setup().
- */
- if (setreuid(-1, save_myuid) < 0) {
- tst_brkm(TBROK, NULL,
- "resetting process real/effective uid failed");
- }
-
- tst_rmdir();
-
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .needs_root = 1,
+ .needs_tmpdir = 1
+};
diff --git a/testcases/kernel/syscalls/mlock/mlock01.c b/testcases/kernel/syscalls/mlock/mlock01.c
index 2338d4d56..0b079f8be 100644
--- a/testcases/kernel/syscalls/mlock/mlock01.c
+++ b/testcases/kernel/syscalls/mlock/mlock01.c
@@ -1,145 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2002
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- * mlock01.c
- *
- * DESCRIPTION
- * Test to see that mlock works
- *$
- * ALGORITHM
- * test 1:
- * Call mlock with various valid addresses and lengths. No
- * error should be returned
- *
- * USAGE: <for command-line>
- * -c n Run n copies concurrently
- * -e Turn on errno logging
- * -f Turn off functional testing
- * -h Show this help screen
- * -i n Execute test n times
- * -I x Execute test for x seconds
- * -p Pause for SIGUSR1 before starting
- * -P x Pause for x seconds between iterations
- * -t Turn on syscall timing
+ * Copyright (c) International Business Machines Corp., 2002
*
* HISTORY
* 06/2002 Written by Paul Larson
- *
- * RESTRICTIONS
- * None
*/
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include "test.h"
-void setup();
-void setup1(int);
-void cleanup();
+/*\
+ * [Description]
+ *
+ * Test mlock with various valid addresses and lengths.
+ */
-char *TCID = "mlock01";
-int TST_TOTAL = 4;
+#include <stdlib.h>
+#include "tst_test.h"
-void *addr1;
+static void *addr;
-struct test_case_t {
- void **addr;
+static struct tcase {
+ char *msg;
int len;
- void (*setupfunc) ();
-} TC[] = {
- /* mlock should return ENOMEM when some or all of the address
- * range pointed to by addr and len are not valid mapped pages
- * in the address space of the process
- */
- {
- &addr1, 1, setup1}, {
- &addr1, 1024, setup1}, {
- &addr1, 1024 * 1024, setup1}, {
- &addr1, 1024 * 1024 * 10, setup1}
+} tcases[] = {
+ {"mlock 1 byte", 1},
+ {"mlock 1024 bytes", 1024},
+ {"mlock 1024 * 1024 bytes", 1024 * 1024},
+ {"mlock 1024 * 1024 * 10 bytes", 1024 * 1024 * 10}
};
-#if !defined(UCLINUX)
-
-int main(int ac, char **av)
-{
- int lc, i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- /*
- * FIXME (garrcoop): this should really test out whether or not the
- * process's mappable address space is indeed accessible by the
- * current user, instead of needing to be run by root all the time.
- */
- tst_require_root();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++) {
-
- if (TC[i].setupfunc != NULL)
- TC[i].setupfunc(TC[i].len);
-
- TEST(mlock(*(TC[i].addr), TC[i].len));
-
- /* I'm confused -- given the description above this
- * should fail as designed, but this application
- * */
- if (TEST_RETURN == -1)
- tst_resm(TFAIL | TTERRNO, "mlock failed");
- else
- tst_resm(TPASS, "mlock passed");
- }
- }
-
- cleanup();
-
- tst_exit();
-}
-
-#else
-
-int main(void)
+static void do_mlock(unsigned int i)
{
- tst_brkm(TCONF, NULL, "test is not available on uClinux");
-}
-
-#endif /* if !defined(UCLINUX) */
+ struct tcase *tc = &tcases[i];
-void setup(void)
-{
- TEST_PAUSE;
+ tst_res(TINFO, "%s", tc->msg);
+ addr = SAFE_MALLOC(tc->len);
+ TST_EXP_PASS(mlock(addr, tc->len), "mlock(%p, %d)", addr, tc->len);
+ free(addr);
+ addr = NULL;
}
-void setup1(int len)
+static void cleanup(void)
{
- addr1 = malloc(len);
- if (addr1 == NULL)
- tst_brkm(TFAIL, cleanup, "malloc failed");
+ if (addr)
+ free(addr);
}
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .needs_root = 1,
+ .test = do_mlock,
+ .tcnt = ARRAY_SIZE(tcases),
+ .cleanup = cleanup,
+};
diff --git a/testcases/kernel/syscalls/mlock/mlock02.c b/testcases/kernel/syscalls/mlock/mlock02.c
index 50ee31d1c..921ddeeae 100644
--- a/testcases/kernel/syscalls/mlock/mlock02.c
+++ b/testcases/kernel/syscalls/mlock/mlock02.c
@@ -1,109 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2002
- * 06/2002 Written by Paul Larson
+ * Copyright (c) International Business Machines Corp., 2002
*
- * 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, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 06/2002 Written by Paul Larson
*/
-/*
- * Test Description:
- * Verify that,
- * 1. mlock() fails with -1 return value and sets errno to ENOMEM,
- * if some of the specified address range does not correspond to
- * mapped pages in the address space of the process.
- * 2. mlock() fails with -1 return value and sets errno to ENOMEM,
- * if (Linux 2.6.9 and later) the caller had a non-zero RLIMIT_MEMLOCK
- * soft resource limit, but tried to lock more memory than the limit
- * permitted. This limit is not enforced if the process is privileged
- * (CAP_IPC_LOCK).
- * 3. mlock() fails with -1 return value and sets errno to EPERM,
- * if (Linux 2.6.9 and later) the caller was not privileged (CAP_IPC_LOCK)
- * and its RLIMIT_MEMLOCK soft resource limit was 0.
+/*\
+ * [Description]
+ *
+ * Test for ENOMEM, EPERM errors.
+ *
+ * 1) mlock(2) fails with ENOMEM if some of the specified address range
+ * does not correspond to mapped pages in the address space of
+ * the process.
+ *
+ * 2) mlock(2) fails with ENOMEM if the caller had a non-zero RLIMIT_MEMLOCK
+ * soft resource limit, but tried to lock more memory than the limit
+ * permitted. This limit is not enforced if the process is
+ * privileged (CAP_IPC_LOCK).
+ *
+ * 3) mlock(2) fails with EPERM if the caller was not privileged (CAP_IPC_LOCK)
+ * and its RLIMIT_MEMLOCK soft resource limit was 0.
*/
-#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <sys/types.h>
#include <pwd.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "mlock02";
-
-#if !defined(UCLINUX)
-
-static void setup(void);
-static void cleanup(void);
-static void test_enomem1(void);
-static void test_enomem2(void);
-static void test_eperm(void);
-static void mlock_verify(const void *, const size_t, const int);
+#include "tst_test.h"
static size_t len;
static struct rlimit original;
static struct passwd *ltpuser;
-static void (*test_func[])(void) = { test_enomem1, test_enomem2, test_eperm };
-
-int TST_TOTAL = ARRAY_SIZE(test_func);
-
-int main(int ac, char **av)
-{
- int lc, i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- for (i = 0; i < TST_TOTAL; i++)
- (*test_func[i])();
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_require_root();
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- ltpuser = SAFE_GETPWNAM(cleanup, "nobody");
-
- len = getpagesize();
-
- SAFE_GETRLIMIT(cleanup, RLIMIT_MEMLOCK, &original);
-}
-
static void test_enomem1(void)
{
void *addr;
- struct rlimit rl;
- addr = SAFE_MMAP(cleanup, NULL, len, PROT_READ,
+ addr = SAFE_MMAP(NULL, len, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
-
- SAFE_MUNMAP(cleanup, addr, len);
-
- mlock_verify(addr, len, ENOMEM);
+ SAFE_MUNMAP(addr, len);
+ TST_EXP_FAIL(mlock(addr, len), ENOMEM, "mlock(%p, %lu)", addr, len);
}
static void test_enomem2(void)
@@ -113,20 +50,14 @@ static void test_enomem2(void)
rl.rlim_max = len - 1;
rl.rlim_cur = len - 1;
- SAFE_SETRLIMIT(cleanup, RLIMIT_MEMLOCK, &rl);
-
- addr = SAFE_MMAP(cleanup, NULL, len, PROT_READ,
+ SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &rl);
+ addr = SAFE_MMAP(NULL, len, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
-
- SAFE_SETEUID(cleanup, ltpuser->pw_uid);
-
- mlock_verify(addr, len, ENOMEM);
-
- SAFE_SETEUID(cleanup, 0);
-
- SAFE_MUNMAP(cleanup, addr, len);
-
- SAFE_SETRLIMIT(cleanup, RLIMIT_MEMLOCK, &original);
+ SAFE_SETEUID(ltpuser->pw_uid);
+ TST_EXP_FAIL(mlock(addr, len), ENOMEM, "mlock(%p, %lu)", addr, len);
+ SAFE_SETEUID(0);
+ SAFE_MUNMAP(addr, len);
+ SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &original);
}
static void test_eperm(void)
@@ -136,51 +67,32 @@ static void test_eperm(void)
rl.rlim_max = 0;
rl.rlim_cur = 0;
- SAFE_SETRLIMIT(cleanup, RLIMIT_MEMLOCK, &rl);
-
- addr = SAFE_MMAP(cleanup, NULL, len, PROT_READ,
+ SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &rl);
+ addr = SAFE_MMAP(NULL, len, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
-
- SAFE_SETEUID(cleanup, ltpuser->pw_uid);
-
- mlock_verify(addr, len, EPERM);
-
- SAFE_SETEUID(cleanup, 0);
-
- SAFE_MUNMAP(cleanup, addr, len);
-
- SAFE_SETRLIMIT(cleanup, RLIMIT_MEMLOCK, &original);
+ SAFE_SETEUID(ltpuser->pw_uid);
+ TST_EXP_FAIL(mlock(addr, len), EPERM, "mlock(%p, %lu)", addr, len);
+ SAFE_SETEUID(0);
+ SAFE_MUNMAP(addr, len);
+ SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &original);
}
-static void mlock_verify(const void *addr, const size_t len, const int error)
+static void run(void)
{
- TEST(mlock(addr, len));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "mlock succeeded unexpectedly");
- return;
- }
-
- if (TEST_ERRNO != error) {
- tst_resm(TFAIL | TTERRNO,
- "mlock didn't fail as expected; expected - %d : %s",
- error, strerror(error));
- } else {
- tst_resm(TPASS | TTERRNO, "mlock failed as expected");
- }
+ test_enomem1();
+ test_enomem2();
+ test_eperm();
}
-static void cleanup(void)
-{
-}
-
-#else
-
-int TST_TOTAL = 1;
-
-int main(void)
+static void setup(void)
{
- tst_brkm(TCONF, NULL, "test is not available on uClinux");
+ ltpuser = SAFE_GETPWNAM("nobody");
+ len = getpagesize();
+ SAFE_GETRLIMIT(RLIMIT_MEMLOCK, &original);
}
-#endif /* if !defined(UCLINUX) */
+static struct tst_test test = {
+ .needs_root = 1,
+ .setup = setup,
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/mlock/mlock03.c b/testcases/kernel/syscalls/mlock/mlock03.c
index 8bc65701c..3700b64b0 100644
--- a/testcases/kernel/syscalls/mlock/mlock03.c
+++ b/testcases/kernel/syscalls/mlock/mlock03.c
@@ -1,5 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ */
+
+/*\
+ * [Description]
+ *
+ * This case is a regression test on old RHEL5.
+ *
* Stack size mapping is decreased through mlock/munlock call.
+ * See the following url:
+ * https://bugzilla.redhat.com/show_bug.cgi?id=643426
*
* This is to test kernel if it has a problem with shortening [stack]
* mapping through several loops of mlock/munlock of /proc/self/maps.
@@ -11,109 +22,61 @@
* munlock 44KiB bfefa000-bff05000 rw-p 00000000 00:00 0 [stack]
*
* with more iterations - could drop to 0KiB.
- *
- * Copyright (C) 2010 Red Hat, Inc.
- * 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 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it
- * is free of the rightful claim of any third person regarding
- * infringement or the like. Any license provided herein, whether
- * implied or otherwise, applies only to this software file. Patent
- * licenses, if any, provided herein do not apply to combinations of
- * this program with other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
+
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
-#include "test.h"
+#include <pwd.h>
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
#define KB 1024
-char *TCID = "mlock03";
-int TST_TOTAL = 1;
-
-static void setup(void);
-static void cleanup(void);
-
-int main(int argc, char *argv[])
+static void verify_mlock(void)
{
- int lc;
long from, to;
long first = -1, last = -1;
char b[KB];
FILE *fp;
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
+ fp = SAFE_FOPEN("/proc/self/maps", "r");
+ while (!feof(fp)) {
+ if (!fgets(b, KB - 1, fp))
+ break;
+ b[strlen(b) - 1] = '\0';
+ if (sscanf(b, "%lx-%lx", &from, &to) != 2) {
+ tst_brk(TBROK, "parse %s start and end address failed",
+ b);
+ continue;
+ }
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- fp = fopen("/proc/self/maps", "r");
- if (fp == NULL)
- tst_brkm(TBROK | TERRNO, cleanup, "fopen");
- while (!feof(fp)) {
- if (!fgets(b, KB - 1, fp))
- break;
- b[strlen(b) - 1] = '\0';
- sscanf(b, "%lx-%lx", &from, &to);
+ /* Record the initial stack size. */
+ if (strstr(b, "[stack]") != NULL)
+ first = (to - from) / KB;
- /* Record the initial stack size. */
- if (lc == 0 && strstr(b, "[stack]") != NULL)
- first = (to - from) / KB;
+ tst_res(TINFO, "mlock [%lx,%lx]", from, to);
+ if (mlock((const void *)from, to - from) == -1)
+ tst_res(TINFO | TERRNO, "mlock failed");
- switch (lc & 1) {
- case 0:
- if (mlock((const void *)from, to - from) == -1)
- tst_resm(TINFO | TERRNO,
- "mlock failed");
- break;
- case 1:
- if (munlock((void *)from, to - from) == -1)
- tst_resm(TINFO | TERRNO,
- "munlock failed");
- break;
- default:
- break;
- }
- tst_resm(TINFO, "%s from %lx to %0lx",
- (lc & 1) ? "munlock" : "mlock", from, to);
+ tst_res(TINFO, "munlock [%lx,%lx]", from, to);
+ if (munlock((void *)from, to - from) == -1)
+ tst_res(TINFO | TERRNO, "munlock failed");
- /* Record the final stack size. */
- if (strstr(b, "[stack]") != NULL)
- last = (to - from) / KB;
- }
- fclose(fp);
+ /* Record the final stack size. */
+ if (strstr(b, "[stack]") != NULL)
+ last = (to - from) / KB;
}
- tst_resm(TINFO, "starting stack size is %ld", first);
- tst_resm(TINFO, "final stack size is %ld", last);
+ SAFE_FCLOSE(fp);
+
+ tst_res(TINFO, "starting stack size is %ld", first);
+ tst_res(TINFO, "final stack size is %ld", last);
if (last < first)
- tst_resm(TFAIL, "stack size is decreased.");
+ tst_res(TFAIL, "stack size is decreased.");
else
- tst_resm(TPASS, "stack size is not decreased.");
-
- cleanup();
- tst_exit();
+ tst_res(TPASS, "stack size is not decreased.");
}
-void setup(void)
-{
- tst_require_root();
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
-}
-
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = verify_mlock,
+};
diff --git a/testcases/kernel/syscalls/mlock/mlock04.c b/testcases/kernel/syscalls/mlock/mlock04.c
index 8ac884583..f25460ba1 100644
--- a/testcases/kernel/syscalls/mlock/mlock04.c
+++ b/testcases/kernel/syscalls/mlock/mlock04.c
@@ -1,102 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
/*
- * This is a reproducer copied from one of LKML patch submission,
+ * Copyright (C) 2010 Red Hat, Inc.
+ */
+
+/*\
+ * [Description]
+ *
+ * This is a reproducer copied from one of LKML patch submission
* which subject is
*
* [PATCH] mlock: revert the optimization for dirtying pages and triggering writeback.
+ * url see https://www.spinics.net/lists/kernel/msg1141090.html
*
* "In 5ecfda0, we do some optimization in mlock, but it causes
* a very basic test case(attached below) of mlock to fail. So
* this patch revert it with some tiny modification so that it
* apply successfully with the lastest 38-rc2 kernel."
*
- * Copyright (C) 2010 Red Hat, Inc.
- * 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 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it
- * is free of the rightful claim of any third person regarding
- * infringement or the like. Any license provided herein, whether
- * implied or otherwise, applies only to this software file. Patent
- * licenses, if any, provided herein do not apply to combinations of
- * this program with other software, or any other product whatsoever.
+ * This bug was fixed by kernel
+ * commit fdf4c587a7 ("mlock: operate on any regions with protection != PROT_NONE")
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * As this case does, mmaps a file with PROT_WRITE permissions but without
+ * PROT_READ, so attempt to not unnecessarity break COW during mlock ended up
+ * causing mlock to fail with a permission problem on unfixed kernel.
*/
-#include "test.h"
-#include "safe_macros.h"
-#include "config.h"
-
-char *TCID = "mlock04";
-int TST_TOTAL = 1;
#include <sys/mman.h>
#include <stdio.h>
#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-int fd, file_len = 40960;
-char *testfile = "test_mlock";
+#include "tst_test.h"
+#include "tst_safe_macros.h"
-static void setup(void);
-static void cleanup(void);
+static int fd = -1, file_len = 40960;
+static char *testfile = "test_mlock";
-int main(void)
+static void verify_mlock(void)
{
char *buf;
- int lc;
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- buf = mmap(NULL, file_len, PROT_WRITE, MAP_SHARED, fd, 0);
-
- if (buf == MAP_FAILED)
- tst_brkm(TBROK | TERRNO, cleanup, "mmap");
- if (mlock(buf, file_len) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "mlock");
-
- tst_resm(TINFO, "locked %d bytes from %p", file_len, buf);
-
- if (munlock(buf, file_len) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "munlock");
-
- SAFE_MUNMAP(cleanup, buf, file_len);
- }
-
- tst_resm(TPASS, "test succeeded.");
-
- cleanup();
-
- tst_exit();
+ buf = SAFE_MMAP(NULL, file_len, PROT_WRITE, MAP_SHARED, fd, 0);
+ TST_EXP_PASS(mlock(buf, file_len), "mlock(%p, %d)", buf, file_len);
+ SAFE_MUNLOCK(buf, file_len);
+ SAFE_MUNMAP(buf, file_len);
}
static void setup(void)
{
- tst_tmpdir();
-
- fd = SAFE_OPEN(cleanup, testfile, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
-
- SAFE_FTRUNCATE(cleanup, fd, file_len);
-
- TEST_PAUSE;
+ fd = SAFE_OPEN(testfile, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+ SAFE_FTRUNCATE(fd, file_len);
}
static void cleanup(void)
{
- close(fd);
-
- tst_rmdir();
+ if (fd > -1)
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_mlock,
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "fdf4c587a793"},
+ {}
+ }
+};
diff --git a/testcases/kernel/syscalls/mmap/.gitignore b/testcases/kernel/syscalls/mmap/.gitignore
index 8811226be..4591fdbb9 100644
--- a/testcases/kernel/syscalls/mmap/.gitignore
+++ b/testcases/kernel/syscalls/mmap/.gitignore
@@ -5,7 +5,6 @@
/mmap04
/mmap05
/mmap06
-/mmap07
/mmap08
/mmap09
/mmap10
@@ -18,3 +17,4 @@
/mmap17
/mmap18
/mmap19
+/mmap20
diff --git a/testcases/kernel/syscalls/mmap/mmap02.c b/testcases/kernel/syscalls/mmap/mmap02.c
index 566cc323a..7ffe61fa3 100644
--- a/testcases/kernel/syscalls/mmap/mmap02.c
+++ b/testcases/kernel/syscalls/mmap/mmap02.c
@@ -1,186 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test Description:
- * Call mmap() with prot parameter set to PROT_READ and with the file
- * descriptor being open for read, to map a file creating mapped memory
- * with read access. The minimum file permissions should be 0444.
- *
- * The call should succeed to create the mapped region with required
- * attributes.
+/*\
+ * [Description]
*
- * Expected Result:
- * mmap() should succeed returning the address of the mapped region,
- * the mapped region should contain the contents of the mapped file.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * Verify that, mmap() call with PROT_READ and a file descriptor which is
+ * open for read only, succeeds to map a file creating mapped memory with
+ * read access.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include "test.h"
-#define TEMPFILE "mmapfile"
-
-char *TCID = "mmap02";
-int TST_TOTAL = 1;
+#include <stdlib.h>
+#include "tst_test.h"
+#define TEMPFILE "mmapfile"
+static ssize_t page_sz;
+static int fd;
static char *addr;
-static char *dummy;
-static size_t page_sz;
-static int fildes;
-
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
-{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call mmap to map the temporary file 'TEMPFILE'
- * with read access.
- */
- errno = 0;
- addr = mmap(0, page_sz, PROT_READ,
- MAP_FILE | MAP_SHARED, fildes, 0);
-
- /* Check for the return value of mmap() */
- if (addr == MAP_FAILED) {
- tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE);
- continue;
- }
-
- /*
- * Read the file contents into the dummy
- * string.
- */
- if (read(fildes, dummy, page_sz) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup,
- "reading %s failed", TEMPFILE);
- }
-
- /*
- * Check whether mapped memory region has
- * the file contents.
- */
- if (memcmp(dummy, addr, page_sz)) {
- tst_resm(TFAIL, "mapped memory area contains "
- "invalid data");
- } else {
- tst_resm(TPASS,
- "Functionality of mmap() successful");
- }
-
- /* Clean up things in case we are looping */
- /* Unmap the mapped memory */
- if (munmap(addr, page_sz) != 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "munmapping failed");
- }
- }
-
- cleanup();
- tst_exit();
-}
+static char *buf;
static void setup(void)
{
- char *tst_buff;
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
page_sz = getpagesize();
+ buf = SAFE_MALLOC(page_sz);
+ memset(buf, 'A', page_sz);
- /* Allocate space for the test buffer */
- if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)");
- }
-
- /* Fill the test buffer with the known data */
- memset(tst_buff, 'A', page_sz);
+ fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, page_sz);
- tst_tmpdir();
-
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
- free(tst_buff);
- tst_brkm(TFAIL | TERRNO, cleanup, "opening %s failed",
- TEMPFILE);
- }
-
- /* Write test buffer contents into temporary file */
- if (write(fildes, tst_buff, page_sz) < (int)page_sz) {
- free(tst_buff);
- tst_brkm(TFAIL | TERRNO, cleanup,
- "writing to %s failed", TEMPFILE);
- }
-
- /* Free the memory allocated for test buffer */
- free(tst_buff);
-
- /* Change Mode permissions on Temporary file */
- if (fchmod(fildes, 0444) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "fchmod(%s, 0444) failed",
- TEMPFILE);
- }
-
- /* Close the temporary file */
- if (close(fildes) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "closing %s failed",
- TEMPFILE);
- }
+ SAFE_FCHMOD(fd, 0444);
+ SAFE_CLOSE(fd);
+ fd = SAFE_OPEN(TEMPFILE, O_RDONLY);
+}
- /* Open the temporary file again, - Readonly mode */
- if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
- tst_brkm(TFAIL, cleanup, "reopening %s readonly failed",
- TEMPFILE);
- }
+static void run(void)
+{
+ addr = SAFE_MMAP(NULL, page_sz, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
- /* Allocate and initialize dummy string of system page size bytes */
- if ((dummy = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, cleanup, "calloc failed (dummy)");
- }
+ if (memcmp(buf, addr, page_sz) == 0)
+ tst_res(TPASS, "mmap() functionality successful");
+ else
+ tst_res(TFAIL, "mapped memory area contains invalid data");
+ SAFE_MUNMAP(addr, page_sz);
}
static void cleanup(void)
{
- close(fildes);
- free(dummy);
- tst_rmdir();
+ if (fd > 0)
+ SAFE_CLOSE(fd);
+
+ free(buf);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .needs_tmpdir = 1
+};
diff --git a/testcases/kernel/syscalls/mmap/mmap05.c b/testcases/kernel/syscalls/mmap/mmap05.c
index 82f122543..7abddaa9e 100644
--- a/testcases/kernel/syscalls/mmap/mmap05.c
+++ b/testcases/kernel/syscalls/mmap/mmap05.c
@@ -1,205 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test Description:
- * Call mmap() to map a file creating mapped memory with no access under
- * the following conditions -
- * - The prot parameter is set to PROT_NONE
- * - The file descriptor is open for read(any mode other than write)
- * - The minimum file permissions should be 0444.
- *
- * The call should succeed to map the file creating mapped memory with the
- * required attributes.
- *
- * Expected Result:
- * mmap() should succeed returning the address of the mapped region,
- * and an attempt to access the contents of the mapped region should give
- * rise to the signal SIGSEGV.
+/*\
+ * [Description]
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * Verify that, mmap() call with 'PROT_NONE' and a file descriptor which is
+ * open for read and write, succeeds to map the file creating mapped memory,
+ * but any attempt to access the contents of the mapped region causes the
+ * SIGSEGV signal.
*/
-#include <stdio.h>
+
#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
#include <setjmp.h>
+#include "tst_test.h"
-#include "test.h"
-
-#define TEMPFILE "mmapfile"
-
-char *TCID = "mmap05";
-int TST_TOTAL = 1;
-
+#define TEMPFILE "mmapfile"
static size_t page_sz;
static volatile char *addr;
-static int fildes;
-static volatile int pass = 0;
+static int fd;
+static volatile int sig_flag;
static sigjmp_buf env;
-static void setup(void);
-static void cleanup(void);
-static void sig_handler(int sig);
-
-int main(int ac, char **av)
+static void sig_handler(int sig)
{
- int lc;
- char file_content;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call mmap to map the temporary file 'TEMPFILE'
- * with no access.
- */
- errno = 0;
- addr = mmap(0, page_sz, PROT_NONE,
- MAP_FILE | MAP_SHARED, fildes, 0);
- TEST_ERRNO = errno;
-
- /* Check for the return value of mmap() */
- if (addr == MAP_FAILED) {
- tst_resm(TFAIL | TERRNO, "mmap() failed on %s",
- TEMPFILE);
- continue;
- }
-
- /*
- * Try to access the mapped region. This should
- * generate a SIGSEGV which will be caught below.
- *
- * This is wrapped by the sigsetjmp() call that will
- * take care of restoring the program's context in an
- * elegant way in conjunction with the call to
- * siglongjmp() in the signal handler.
- */
- if (sigsetjmp(env, 1) == 0) {
- file_content = addr[0];
- }
-
- if (pass) {
- tst_resm(TPASS, "Got SIGSEGV as expected");
- } else {
- tst_resm(TFAIL, "Mapped memory region with NO "
- "access is accessible");
- }
-
- /* Unmap mapped memory and reset pass in case we are looping */
- if (munmap((void *)addr, page_sz) != 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "munmap failed");
- }
- pass = 0;
-
+ if (sig == SIGSEGV) {
+ sig_flag = 1;
+ siglongjmp(env, 1);
}
-
- cleanup();
- tst_exit();
}
static void setup(void)
{
- char *tst_buff;
-
- tst_sig(NOFORK, sig_handler, cleanup);
+ char *buf;
- TEST_PAUSE;
+ SAFE_SIGNAL(SIGSEGV, sig_handler);
page_sz = getpagesize();
+ buf = SAFE_MALLOC(page_sz);
+ memset(buf, 'A', page_sz);
- /* Allocate space for the test buffer */
- if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)");
- }
-
- /* Fill the test buffer with the known data */
- memset(tst_buff, 'A', page_sz);
-
- tst_tmpdir();
-
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
- free(tst_buff);
- tst_brkm(TFAIL | TERRNO, cleanup, "opening %s failed",
- TEMPFILE);
- }
+ fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, page_sz);
+ free(buf);
+}
- /* Write test buffer contents into temporary file */
- if (write(fildes, tst_buff, page_sz) != (int)page_sz) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE);
+static void run(void)
+{
+ addr = mmap(NULL, page_sz, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ tst_res(TFAIL | TERRNO, "mmap() of %s failed", TEMPFILE);
+ return;
}
- /* Free the memory allocated for test buffer */
- free(tst_buff);
+ if (sigsetjmp(env, 1) == 0)
+ tst_res(TINFO, "Trying to access mapped region: %c", addr[0]);
- /* Make sure proper permissions set on file */
- if (fchmod(fildes, 0444) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "fchmod of %s failed",
- TEMPFILE);
- }
+ if (sig_flag)
+ tst_res(TPASS, "Received SIGSEGV signal as expected");
+ else
+ tst_res(TFAIL, "SIGSEGV signal not received");
- /* Close the temporary file opened for write */
- if (close(fildes) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "closing %s failed",
- TEMPFILE);
- }
+ SAFE_MUNMAP((char *)addr, page_sz);
- /* Open the temporary file again for reading */
- if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "opening %s readonly failed",
- TEMPFILE);
- }
-}
-
-/*
- * sig_handler() - Signal Catching function.
- * This function gets executed when the test process receives
- * the signal SIGSEGV while trying to access the contents of memory which
- * is not accessible.
- */
-static void sig_handler(int sig)
-{
- if (sig == SIGSEGV) {
- /* set the global variable and jump back */
- pass = 1;
- siglongjmp(env, 1);
- } else {
- tst_brkm(TBROK, cleanup, "received an unexpected signal: %d",
- sig);
- }
+ sig_flag = 0;
}
static void cleanup(void)
{
- close(fildes);
- tst_rmdir();
+ if (fd > 0)
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .needs_tmpdir = 1
+};
diff --git a/testcases/kernel/syscalls/mmap/mmap06.c b/testcases/kernel/syscalls/mmap/mmap06.c
index fb7c49257..615743fa7 100644
--- a/testcases/kernel/syscalls/mmap/mmap06.c
+++ b/testcases/kernel/syscalls/mmap/mmap06.c
@@ -1,143 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test Description:
- * Call mmap() to map a file creating a mapped region with read access
- * under the following conditions -
- * - The prot parameter is set to PROT_READ
- * - The file descriptor is open for writing.
+/*\
+ * [Description]
*
- * The call should fail to map the file.
+ * Verify that, mmap() call fails with errno:
*
- * Expected Result:
- * mmap() should fail returning -1 and errno should get set to EACCES.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * - EACCES, when a file mapping is requested but the file descriptor is not open for reading.
+ * - EINVAL, when length argument is 0.
+ * - EINVAL, when flags contains none of MAP_PRIVATE, MAP_SHARED, or MAP_SHARED_VALIDATE.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include "test.h"
-
-#define TEMPFILE "mmapfile"
-char *TCID = "mmap06";
-int TST_TOTAL = 1;
+#include <stdlib.h>
+#include "tst_test.h"
+#define MMAPSIZE 1024
+#define TEMPFILE "mmapfile"
static size_t page_sz;
-static char *addr;
-static int fildes;
-
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
-{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call mmap to map the temporary file 'TEMPFILE'
- * with read access.
- */
- errno = 0;
- addr = mmap(0, page_sz, PROT_READ,
- MAP_FILE | MAP_SHARED, fildes, 0);
- TEST_ERRNO = errno;
-
- /* Check for the return value of mmap() */
- if (addr != MAP_FAILED) {
- tst_resm(TFAIL | TERRNO,
- "mmap() returned invalid value, expected: %p",
- MAP_FAILED);
- /* Unmap the mapped memory */
- if (munmap(addr, page_sz) != 0) {
- tst_resm(TBROK, "munmap() failed");
- cleanup();
- }
- continue;
- }
- if (TEST_ERRNO == EACCES) {
- tst_resm(TPASS, "mmap failed with EACCES");
- } else {
- tst_resm(TFAIL | TERRNO,
- "mmap failed with unexpected errno");
- }
- }
- cleanup();
- tst_exit();
-
-}
+static int fd;
+
+static struct tcase {
+ size_t length;
+ int prot;
+ int flags;
+ int exp_errno;
+} tcases[] = {
+ {MMAPSIZE, PROT_WRITE, MAP_FILE | MAP_PRIVATE, EACCES},
+ {MMAPSIZE, PROT_WRITE, MAP_FILE | MAP_SHARED, EACCES},
+ {MMAPSIZE, PROT_READ, MAP_FILE | MAP_PRIVATE, EACCES},
+ {MMAPSIZE, PROT_READ, MAP_FILE | MAP_SHARED, EACCES},
+ {MMAPSIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, EACCES},
+ {MMAPSIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, EACCES},
+ {0, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, EINVAL},
+ {MMAPSIZE, PROT_READ | PROT_WRITE, MAP_FILE, EINVAL}
+};
static void setup(void)
{
- char *tst_buff;
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ char *buf;
page_sz = getpagesize();
+ buf = SAFE_MALLOC(page_sz);
+ memset(buf, 'A', page_sz);
- /* Allocate space for the test buffer */
- if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, NULL, "calloc() failed (tst_buff)");
- }
+ fd = SAFE_OPEN(TEMPFILE, O_WRONLY | O_CREAT, 0666);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, page_sz);
+ free(buf);
+}
- /* Fill the test buffer with the known data */
- memset(tst_buff, 'A', page_sz);
+static void run(unsigned int i)
+{
+ struct tcase *tc = &tcases[i];
- tst_tmpdir();
+ TESTPTR(mmap(NULL, tc->length, tc->prot, tc->flags, fd, 0));
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE);
+ if (TST_RET_PTR != MAP_FAILED) {
+ tst_res(TFAIL, "mmap() was successful unexpectedly");
+ SAFE_MUNMAP(TST_RET_PTR, MMAPSIZE);
+ } else if (TST_ERR == tc->exp_errno) {
+ tst_res(TPASS | TERRNO, "mmap() failed with");
+ } else {
+ tst_res(TFAIL | TERRNO, "mmap() failed unexpectedly");
}
-
- /* Write test buffer contents into temporary file */
- if (write(fildes, tst_buff, page_sz) < (ssize_t)page_sz) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE);
- }
-
- free(tst_buff);
}
static void cleanup(void)
{
- close(fildes);
- tst_rmdir();
+ if (fd > 0)
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .needs_tmpdir = 1
+};
diff --git a/testcases/kernel/syscalls/mmap/mmap07.c b/testcases/kernel/syscalls/mmap/mmap07.c
deleted file mode 100644
index 682e527aa..000000000
--- a/testcases/kernel/syscalls/mmap/mmap07.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Test Description:
- * Call mmap() to map a file creating a mapped region with read access
- * under the following conditions -
- * - The prot parameter is set to PROT_WRITE
- * - The file descriptor is open for writing.
- * - The flags parameter has MAP_PRIVATE set.
- *
- * The call should fail to map the file.
- *
- * Expected Result:
- * mmap() should fail returning -1 and errno should get set to EACCES.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include "test.h"
-
-#define TEMPFILE "mmapfile"
-
-char *TCID = "mmap07";
-int TST_TOTAL = 1;
-
-static size_t page_sz;
-static char *addr;
-static int fildes;
-
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
-{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call mmap to map the temporary file 'TEMPFILE'
- * with write access.
- */
- errno = 0;
- addr = mmap(0, page_sz, PROT_WRITE,
- MAP_FILE | MAP_PRIVATE, fildes, 0);
- TEST_ERRNO = errno;
-
- /* Check for the return value of mmap() */
- if (addr != MAP_FAILED) {
- tst_resm(TFAIL | TERRNO,
- "mmap() returned invalid value, expected: %p",
- MAP_FAILED);
- /* Unmap the mapped memory */
- if (munmap(addr, page_sz) != 0) {
- tst_resm(TBROK, "munmap() failed");
- cleanup();
- }
- continue;
- }
- if (TEST_ERRNO == EACCES) {
- tst_resm(TPASS, "mmap failed with EACCES");
- } else {
- tst_resm(TFAIL | TERRNO,
- "mmap failed with unexpected errno");
- }
-
- }
- cleanup();
- tst_exit();
-
-}
-
-static void setup(void)
-{
- char *tst_buff;
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- page_sz = getpagesize();
-
- /* Allocate space for the test buffer */
- if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, NULL,
- "calloc() failed to allocate space for tst_buff");
- }
-
- /* Fill the test buffer with the known data */
- memset(tst_buff, 'A', page_sz);
-
- tst_tmpdir();
-
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "open() on %s failed", TEMPFILE);
- }
-
- /* Write test buffer contents into temporary file */
- if (write(fildes, tst_buff, page_sz) < (int)page_sz) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE);
- }
-
- free(tst_buff);
-}
-
-static void cleanup(void)
-{
- close(fildes);
- tst_rmdir();
-}
diff --git a/testcases/kernel/syscalls/mmap/mmap08.c b/testcases/kernel/syscalls/mmap/mmap08.c
index f2daf45a3..5c9fd782c 100644
--- a/testcases/kernel/syscalls/mmap/mmap08.c
+++ b/testcases/kernel/syscalls/mmap/mmap08.c
@@ -1,142 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test Description:
- * Verify that mmap() fails to map a file creating a mapped region
- * when the file specified by file descriptor is not valid.
- *
- * Expected Result:
- * mmap() should fail returning -1 and errno should get set to EBADF.
+/*\
+ * [Description]
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * verify that, mmap() calls fails with errno EBADF when a file mapping
+ * is requested but the fd is not a valid file descriptor.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include "test.h"
-#define TEMPFILE "mmapfile"
-
-char *TCID = "mmap08";
-int TST_TOTAL = 1;
+#include <stdlib.h>
+#include "tst_test.h"
+#define TEMPFILE "mmapfile"
static size_t page_sz;
-static char *addr;
-static int fildes;
+static int fd;
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
+static void setup(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call mmap to map the temporary file 'TEMPFILE'
- * which is already closed. so, fildes is not valid.
- */
- errno = 0;
- addr = mmap(0, page_sz, PROT_WRITE,
- MAP_FILE | MAP_SHARED, fildes, 0);
- TEST_ERRNO = errno;
-
- /* Check for the return value of mmap() */
- if (addr != MAP_FAILED) {
- tst_resm(TFAIL, "mmap() didn't fail (%p != %p)",
- addr, MAP_FAILED);
- /* Unmap the mapped memory */
- if (munmap(addr, page_sz) != 0) {
- tst_brkm(TBROK, cleanup, "munmap() failed");
- }
- continue;
- }
- if (TEST_ERRNO == EBADF) {
- tst_resm(TPASS, "mmap failed with EBADF");
- } else {
- tst_resm(TFAIL | TERRNO,
- "mmap failed with an invalid errno");
- }
- }
-
- cleanup();
- tst_exit();
+ fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
+ SAFE_CLOSE(fd);
}
-static void setup(void)
+static void run(void)
{
- char *tst_buff;
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- page_sz = getpagesize();
-
- if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, NULL,
- "calloc() failed to allocate space for tst_buff");
- }
-
- /* Fill the test buffer with the known data */
- memset(tst_buff, 'A', page_sz);
-
- tst_tmpdir();
-
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE);
- }
-
- /* Write test buffer contents into temporary file */
- if (write(fildes, tst_buff, page_sz) != (int)page_sz) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE);
- }
-
- /* Free the memory allocated for test buffer */
- free(tst_buff);
-
- /* Close the temporary file opened for writing */
- if (close(fildes) < 0) {
- tst_brkm(TFAIL, cleanup, "closing %s failed", TEMPFILE);
+ TESTPTR(mmap(NULL, page_sz, PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0));
+
+ if (TST_RET_PTR != MAP_FAILED) {
+ tst_res(TFAIL, "mmap() passed unexpectedly");
+ SAFE_MUNMAP(TST_RET_PTR, page_sz);
+ } else if (TST_ERR == EBADF) {
+ tst_res(TPASS, "mmap() failed with EBADF");
+ } else {
+ tst_res(TFAIL | TERRNO, "mmap() failed with an invalid errno");
}
}
static void cleanup(void)
{
- tst_rmdir();
+ if (fd > 0)
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .needs_tmpdir = 1
+};
diff --git a/testcases/kernel/syscalls/mmap/mmap17.c b/testcases/kernel/syscalls/mmap/mmap17.c
index a8136a0b2..39703fbd3 100644
--- a/testcases/kernel/syscalls/mmap/mmap17.c
+++ b/testcases/kernel/syscalls/mmap/mmap17.c
@@ -17,7 +17,6 @@
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
-#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
diff --git a/testcases/kernel/syscalls/mmap/mmap20.c b/testcases/kernel/syscalls/mmap/mmap20.c
new file mode 100644
index 000000000..02d150e45
--- /dev/null
+++ b/testcases/kernel/syscalls/mmap/mmap20.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Paulson Raja L <paulson@zilogic.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Test mmap(2) with MAP_SHARED_VALIDATE flag.
+ *
+ * Test expected EOPNOTSUPP errno when testing mmap(2) with MAP_SHARED_VALIDATE
+ * flag and invalid flag.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include "tst_test.h"
+#include "lapi/mmap.h"
+
+#define TEST_FILE "file_to_mmap"
+#define TEST_FILE_SIZE 1024
+#define INVALID_FLAG (1 << 10)
+
+static int fd = -1;
+static void *addr;
+
+static void setup(void)
+{
+ fd = SAFE_OPEN(TEST_FILE, O_CREAT | O_RDWR, 0600);
+
+ if (tst_fill_file(TEST_FILE, 'a', TEST_FILE_SIZE, 1))
+ tst_brk(TBROK, "Could not fill the testfile");
+}
+
+static void cleanup(void)
+{
+ if (fd > -1)
+ SAFE_CLOSE(fd);
+
+ if (addr && addr != MAP_FAILED)
+ SAFE_MUNMAP(addr, TEST_FILE_SIZE);
+}
+
+static void test_mmap(void)
+{
+ addr = mmap(NULL, TEST_FILE_SIZE, PROT_READ | PROT_WRITE,
+ INVALID_FLAG | MAP_SHARED_VALIDATE, fd, 0);
+
+ if (addr != MAP_FAILED)
+ tst_res(TFAIL | TERRNO, "mmap() is successful, but it should have failed");
+ else if (errno == EOPNOTSUPP)
+ tst_res(TPASS, "mmap() failed with errno set to EOPNOTSUPP");
+ else
+ tst_res(TFAIL | TERRNO, "mmap() failed with unexpected error");
+}
+
+static struct tst_test test = {
+ .min_kver = "4.15",
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = test_mmap,
+ .needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/mount/.gitignore b/testcases/kernel/syscalls/mount/.gitignore
index f92600d36..80885dbf0 100644
--- a/testcases/kernel/syscalls/mount/.gitignore
+++ b/testcases/kernel/syscalls/mount/.gitignore
@@ -5,3 +5,4 @@
/mount04
/mount05
/mount06
+/mount07
diff --git a/testcases/kernel/syscalls/mount/mount03.c b/testcases/kernel/syscalls/mount/mount03.c
index 60f9963da..98d5933b7 100644
--- a/testcases/kernel/syscalls/mount/mount03.c
+++ b/testcases/kernel/syscalls/mount/mount03.c
@@ -122,7 +122,7 @@ static void test_file_dir_noatime(int update_fatime, int update_datime)
SAFE_CLOSEDIR(test_dir);
dir_atime = dir_st.st_atime;
- sleep(1);
+ usleep(1001000);
SAFE_READ(0, otfd, readbuf, sizeof(readbuf));
SAFE_FSTAT(otfd, &st);
diff --git a/testcases/kernel/syscalls/mount/mount07.c b/testcases/kernel/syscalls/mount/mount07.c
new file mode 100644
index 000000000..eb3fb55a0
--- /dev/null
+++ b/testcases/kernel/syscalls/mount/mount07.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test for MS_NOSYMFOLLOW mount option and is copied
+ * from kernel selftests nosymfollow-test.c.
+ *
+ * It tests to make sure that symlink traversal fails with ELOOP when
+ * 'nosymfollow' is set, but symbolic links can still be created, and
+ * readlink(2) and realpath(3) still work properly. It also verifies
+ * that statfs(2) correctly returns ST_NOSYMFOLLOW.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <stdbool.h>
+#include "tst_test.h"
+#include "lapi/mount.h"
+
+#ifndef ST_NOSYMFOLLOW
+# define ST_NOSYMFOLLOW 0x2000
+#endif
+
+#define MNTPOINT "mntpoint"
+
+static char test_file[PATH_MAX];
+static char link_file[PATH_MAX];
+static char temp_link_file[PATH_MAX];
+static int flag;
+
+static void setup_symlink(void)
+{
+ int fd;
+
+ fd = SAFE_CREAT(test_file, O_RDWR);
+ SAFE_SYMLINK(test_file, link_file);
+ SAFE_CLOSE(fd);
+ flag = 1;
+}
+
+static void test_link_traversal(bool nosymfollow)
+{
+ if (nosymfollow) {
+ TST_EXP_FAIL2(open(link_file, 0, O_RDWR), ELOOP,
+ "open(%s, 0, O_RDWR)", link_file);
+ } else {
+ TST_EXP_FD(open(link_file, 0, O_RDWR));
+ }
+
+ if (TST_RET > 0)
+ SAFE_CLOSE(TST_RET);
+}
+
+static void test_readlink(void)
+{
+ char buf[4096];
+
+ memset(buf, 0, 4096);
+ TST_EXP_POSITIVE(readlink(link_file, buf, sizeof(buf)),
+ "readlink(%s, buf, %ld)", link_file, sizeof(buf));
+ if (strcmp(buf, test_file) != 0) {
+ tst_res(TFAIL, "readlink strcmp failed, %s, %s",
+ buf, test_file);
+ } else {
+ tst_res(TPASS, "readlink strcmp succeeded");
+ }
+}
+
+static void test_realpath(void)
+{
+ TESTPTR(realpath(link_file, NULL));
+
+ if (!TST_RET_PTR) {
+ tst_res(TFAIL | TERRNO, "realpath failed");
+ return;
+ }
+
+ if (strcmp(TST_RET_PTR, test_file) != 0) {
+ tst_res(TFAIL, "realpath strcmp failed, %s, %s",
+ (char *)TST_RET_PTR, test_file);
+ } else {
+ tst_res(TPASS, "realpath strcmp succeeded");
+ }
+}
+
+static void test_cycle_link(void)
+{
+ TST_EXP_PASS(symlink(test_file, temp_link_file), "symlink(%s, %s)",
+ test_file, temp_link_file);
+ TST_EXP_PASS(unlink(temp_link_file));
+}
+
+static void test_statfs(bool nosymfollow)
+{
+ struct statfs buf;
+
+ SAFE_STATFS(MNTPOINT, &buf);
+ if (buf.f_flags & ST_NOSYMFOLLOW) {
+ tst_res(nosymfollow ? TPASS : TFAIL, "ST_NOSYMFOLLOW set on %s",
+ MNTPOINT);
+ } else {
+ tst_res(nosymfollow ? TFAIL : TPASS, "ST_NOSYMFOLLOW not set on %s",
+ MNTPOINT);
+ }
+}
+
+static void setup(void)
+{
+ char *tmpdir = tst_get_tmpdir();
+
+ snprintf(test_file, PATH_MAX, "%s/%s/test_file", tst_get_tmpdir(),
+ MNTPOINT);
+ snprintf(link_file, PATH_MAX, "%s/%s/link_file", tst_get_tmpdir(),
+ MNTPOINT);
+ snprintf(temp_link_file, PATH_MAX, "%s/%s/temp_link_file",
+ tst_get_tmpdir(), MNTPOINT);
+ free(tmpdir);
+}
+
+static void cleanup(void)
+{
+ if (tst_is_mounted(MNTPOINT))
+ SAFE_UMOUNT(MNTPOINT);
+}
+
+static void run_tests(bool nosymfollow)
+{
+ test_link_traversal(nosymfollow);
+ test_readlink();
+ test_realpath();
+ test_cycle_link();
+ test_statfs(nosymfollow);
+}
+
+static void run(void)
+{
+ tst_res(TINFO, "Testing behaviour when not setting MS_NOSYMFOLLOW");
+
+ TST_EXP_PASS_SILENT(mount(tst_device->dev, MNTPOINT, tst_device->fs_type,
+ 0, NULL));
+ if (!flag || !strcmp(tst_device->fs_type, "tmpfs"))
+ setup_symlink();
+ run_tests(false);
+
+ tst_res(TINFO, "Testing behaviour when setting MS_NOSYMFOLLOW");
+ TST_EXP_PASS_SILENT(mount(tst_device->dev, MNTPOINT, tst_device->fs_type,
+ MS_REMOUNT | MS_NOSYMFOLLOW, NULL));
+ run_tests(true);
+
+ SAFE_UMOUNT(MNTPOINT);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .forks_child = 1,
+ .needs_root = 1,
+ .min_kver = "5.10",
+ .format_device = 1,
+ .mntpoint = MNTPOINT,
+ .all_filesystems = 1,
+ .skip_filesystems = (const char *const []){
+ "exfat",
+ "vfat",
+ "ntfs",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/mount_setattr/mount_setattr01.c b/testcases/kernel/syscalls/mount_setattr/mount_setattr01.c
index 83746b878..e500df28e 100644
--- a/testcases/kernel/syscalls/mount_setattr/mount_setattr01.c
+++ b/testcases/kernel/syscalls/mount_setattr/mount_setattr01.c
@@ -32,7 +32,6 @@
#include <sys/statvfs.h>
#include "tst_test.h"
#include "lapi/fsmount.h"
-#include "lapi/stat.h"
#define MNTPOINT "mntpoint"
#define OT_MNTPOINT "ot_mntpoint"
diff --git a/testcases/kernel/syscalls/mprotect/.gitignore b/testcases/kernel/syscalls/mprotect/.gitignore
index 9571ffd43..929c3b3a2 100644
--- a/testcases/kernel/syscalls/mprotect/.gitignore
+++ b/testcases/kernel/syscalls/mprotect/.gitignore
@@ -2,3 +2,4 @@
/mprotect02
/mprotect03
/mprotect04
+/mprotect05
diff --git a/testcases/kernel/syscalls/mprotect/mprotect05.c b/testcases/kernel/syscalls/mprotect/mprotect05.c
new file mode 100644
index 000000000..2b15f5beb
--- /dev/null
+++ b/testcases/kernel/syscalls/mprotect/mprotect05.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All Rights Reserved.
+ * Author: Liam R. Howlett <liam.howlett@oracle.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Testcase to check the mprotect(2) system call split and merge.
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=217061
+ *
+ */
+
+#include "tst_test.h"
+
+#define TEST_FILE "mprotect05-testfile"
+
+static int fd;
+static char *addr = MAP_FAILED;
+static unsigned long pagesize;
+static unsigned long fullsize;
+
+static void setup(void)
+{
+ pagesize = getpagesize();
+ fullsize = 5 * pagesize;
+}
+
+static void run(void)
+{
+ fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT, 0777);
+ addr = SAFE_MMAP(0, fullsize, PROT_READ, MAP_SHARED, fd, 0);
+
+ if (mprotect(addr + pagesize, pagesize, PROT_EXEC))
+ tst_res(TFAIL | TERRNO, "mprotect failed to exec");
+
+ if (mprotect(addr + 3 * pagesize, pagesize, PROT_WRITE))
+ tst_res(TFAIL | TERRNO, "mprotect failed to write");
+
+ if (mprotect(addr + pagesize, pagesize * 4, PROT_READ))
+ tst_res(TFAIL | TERRNO, "mprotect failed to read");
+
+ SAFE_MUNMAP(addr, fullsize);
+ SAFE_CLOSE(fd);
+ addr = MAP_FAILED;
+ SAFE_UNLINK(TEST_FILE);
+ tst_res(TPASS, "test passed");
+}
+
+static void cleanup(void)
+{
+ if (addr != MAP_FAILED) {
+ SAFE_MUNMAP(addr, fullsize);
+ SAFE_CLOSE(fd);
+ }
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "2fcd07b7ccd5"},
+ {}
+ },
+};
diff --git a/testcases/kernel/syscalls/mq_notify/.gitignore b/testcases/kernel/syscalls/mq_notify/.gitignore
index cca05a7fa..3f9403c05 100644
--- a/testcases/kernel/syscalls/mq_notify/.gitignore
+++ b/testcases/kernel/syscalls/mq_notify/.gitignore
@@ -1,2 +1,3 @@
/mq_notify01
/mq_notify02
+/mq_notify03
diff --git a/testcases/kernel/syscalls/mq_notify/mq_notify02.c b/testcases/kernel/syscalls/mq_notify/mq_notify02.c
index 3109fe345..d979a4e9d 100644
--- a/testcases/kernel/syscalls/mq_notify/mq_notify02.c
+++ b/testcases/kernel/syscalls/mq_notify/mq_notify02.c
@@ -1,91 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014 Fujitsu Ltd.
- * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
- *
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program.
+ * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * ALGORITHM
- * test 1:
- * sevp->sigev_notify = -1, EINVAL should be returned.
- * test 2:
- * sevp->sigev_notify = SIGEV_SIGNAL and sevp->sigev_signo > _NSG,
- * EINVAL should be returned.
+
+/*\
+ * [Description]
+ *
+ * This test verifies that mq_notify() fails with EINVAL when invalid input
+ * arguments are given.
*/
-#include <errno.h>
#include <mqueue.h>
-#include "test.h"
-
-char *TCID = "mq_notify02";
-static void setup(void);
-static void cleanup(void);
+#include "tst_test.h"
static struct test_case_t {
struct sigevent sevp;
int exp_errno;
-} test_cases[] = {
+} tcase[] = {
{{.sigev_notify = -1}, EINVAL},
- {{.sigev_notify = SIGEV_SIGNAL, .sigev_signo = _NSIG+1}, EINVAL},
+ {{.sigev_notify = SIGEV_SIGNAL, .sigev_signo = _NSIG + 1}, EINVAL},
};
-int TST_TOTAL = ARRAY_SIZE(test_cases);
-static void mq_notify_verify(struct test_case_t *);
-
-int main(int argc, char **argv)
-{
- int lc;
- int i;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- for (i = 0; i < TST_TOTAL; i++)
- mq_notify_verify(&test_cases[i]);
- }
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
+static void run(unsigned int i)
{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ struct test_case_t *test = &tcase[i];
- TEST_PAUSE;
+ TST_EXP_FAIL(mq_notify(0, &(test->sevp)), test->exp_errno);
}
-static void mq_notify_verify(struct test_case_t *test)
-{
- TEST(mq_notify(0, &(test->sevp)));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "mq_notify() succeeded unexpectedly");
- return;
- }
-
- if (TEST_ERRNO == test->exp_errno) {
- tst_resm(TPASS | TTERRNO, "mq_notify failed as expected");
- } else if (TEST_ERRNO == ENOSYS) {
- tst_resm(TCONF | TTERRNO, "mq_notify not available");
- } else {
- tst_resm(TFAIL | TTERRNO,
- "mq_notify failed unexpectedly; expected: %d - %s",
- test->exp_errno, strerror(test->exp_errno));
- }
-}
-
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .tcnt = ARRAY_SIZE(tcase),
+ .test = run,
+};
diff --git a/testcases/kernel/syscalls/mq_notify/mq_notify03.c b/testcases/kernel/syscalls/mq_notify/mq_notify03.c
new file mode 100644
index 000000000..bf6898cd8
--- /dev/null
+++ b/testcases/kernel/syscalls/mq_notify/mq_notify03.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) The GNU Toolchain Authors.
+ * Copyright (c) 2023 Wei Gao <wegao@suse.com>
+ *
+ */
+
+/*\
+ * [Description]
+ *
+ * Test for NULL pointer dereference in mq_notify(CVE-2021-38604)
+ *
+ * References links:
+ * - https://sourceware.org/bugzilla/show_bug.cgi?id=28213
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <mqueue.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include "tst_test.h"
+#include "tst_safe_posix_ipc.h"
+
+static mqd_t m = -1;
+static const char msg[] = "hello";
+
+static void try_null_dereference_cb(union sigval sv)
+{
+ char buf[sizeof(msg)];
+
+ (void)sv;
+
+ TST_EXP_VAL((size_t) mq_receive(m, buf, sizeof(buf), NULL),
+ sizeof(buf));
+ TST_EXP_PASS(memcmp(buf, msg, sizeof(buf)));
+
+ exit(0);
+}
+
+static void try_null_dereference(void)
+{
+ struct sigevent sev;
+
+ memset(&sev, '\0', sizeof(sev));
+ sev.sigev_notify = SIGEV_THREAD;
+ sev.sigev_notify_function = try_null_dereference_cb;
+
+ /* Step 1: Register & unregister notifier.
+ * Helper thread should receive NOTIFY_REMOVED notification.
+ * In a vulnerable version of glibc, NULL pointer dereference follows.
+ */
+ TST_EXP_PASS(mq_notify(m, &sev));
+ TST_EXP_PASS(mq_notify(m, NULL));
+
+ /* Step 2: Once again, register notification.
+ * Try to send one message.
+ * Test is considered successful, if the callback does exit (0).
+ */
+ TST_EXP_PASS(mq_notify(m, &sev));
+ TST_EXP_PASS(mq_send(m, msg, sizeof(msg), 1));
+
+ /* Wait... */
+ pause();
+}
+
+static void do_test(void)
+{
+ static const char m_name[] = "/ltp_mq_notify03";
+ struct mq_attr m_attr;
+
+ memset(&m_attr, '\0', sizeof(m_attr));
+ m_attr.mq_maxmsg = 1;
+ m_attr.mq_msgsize = sizeof(msg);
+
+ m = SAFE_MQ_OPEN(m_name,
+ O_RDWR | O_CREAT | O_EXCL,
+ 0600,
+ &m_attr);
+
+ TST_EXP_PASS(mq_unlink(m_name));
+
+ try_null_dereference();
+}
+
+
+static struct tst_test test = {
+ .test_all = do_test,
+ .tags = (const struct tst_tag[]) {
+ {"glibc-git", "b805aebd42"},
+ {"CVE", "2021-38604"},
+ {}
+ },
+ .needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/mremap/.gitignore b/testcases/kernel/syscalls/mremap/.gitignore
index 833e1b883..ec15a19cd 100644
--- a/testcases/kernel/syscalls/mremap/.gitignore
+++ b/testcases/kernel/syscalls/mremap/.gitignore
@@ -3,3 +3,4 @@
/mremap03
/mremap04
/mremap05
+/mremap06
diff --git a/testcases/kernel/syscalls/mremap/mremap06.c b/testcases/kernel/syscalls/mremap/mremap06.c
new file mode 100644
index 000000000..a19262750
--- /dev/null
+++ b/testcases/kernel/syscalls/mremap/mremap06.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 SUSE LLC
+ * Author: Vlastimil Babka <vbabka@suse.cz>
+ * https://bugzilla.suse.com/attachment.cgi?id=867254
+ * LTP port: Petr Vorel <pvorel@suse.cz>
+ */
+
+/*\
+ * [Description]
+ *
+ * Bug reproducer for 7e7757876f25 ("mm/mremap: fix vm_pgoff in vma_merge() case 3")
+ */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "tst_test.h"
+#include "tst_safe_macros.h"
+
+#define NUM_PAGES 3
+
+static int fd;
+static char *buf, *buf2;
+static int page_size, mmap_size, mremap_size;
+
+static struct tcase {
+ size_t incompatible;
+ const char *desc;
+} tcases[] = {
+ {
+ .desc = "all pages with compatible mapping",
+ },
+ {
+ .incompatible = 3,
+ .desc = "third page's mapping incompatible",
+ },
+ {
+ .incompatible = 1,
+ .desc = "first page's mapping incompatible",
+ },
+};
+
+static int check_pages(void)
+{
+ int fail = 0, i;
+ char val;
+
+ for (i = 0; i < (int)ARRAY_SIZE(tcases); i++) {
+ val = buf[i * page_size];
+ if (val != 0x30 + i) {
+ tst_res(TFAIL, "page %d wrong value %d (0x%x)", i, val - 0x30, val);
+ fail = 1;
+ }
+ }
+
+ return fail;
+}
+
+static void do_test(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+ int ret;
+
+ tst_res(TINFO, "%s", tc->desc);
+
+ buf = SAFE_MMAP(0, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+
+ buf2 = mremap(buf + page_size, page_size, page_size,
+ MREMAP_MAYMOVE|MREMAP_FIXED, buf + mremap_size);
+ if (buf2 == MAP_FAILED)
+ tst_brk(TBROK, "mremap() failed");
+
+ if (tc->incompatible) {
+ ret = mprotect(buf + (tc->incompatible-1)*page_size, page_size, PROT_READ);
+ if (ret == -1)
+ tst_brk(TBROK, "mprotect() failed");
+ }
+
+ buf2 = mremap(buf + mremap_size, page_size, page_size,
+ MREMAP_MAYMOVE|MREMAP_FIXED, buf + page_size);
+ if (buf2 == MAP_FAILED)
+ tst_brk(TBROK, "mremap() failed");
+
+ if (!check_pages())
+ tst_res(TPASS, "mmap/mremap work properly");
+
+ SAFE_MUNMAP(buf, mremap_size);
+}
+
+static void setup(void)
+{
+ int ret, i;
+
+ page_size = getpagesize();
+ mmap_size = (NUM_PAGES+1) * page_size;
+ mremap_size = NUM_PAGES * page_size;
+
+ fd = SAFE_OPEN("testfile", O_CREAT | O_RDWR | O_TRUNC, 0600);
+
+ ret = fallocate(fd, 0, 0, mmap_size);
+ if (ret == -1)
+ tst_brk(TBROK, "fallocate() failed");
+
+ buf = SAFE_MMAP(0, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+
+ for (i = 0; i < (int)ARRAY_SIZE(tcases)+1; i++)
+ buf[i*page_size] = 0x30 + i;
+
+ /* clear the page tables */
+ SAFE_MUNMAP(buf, mmap_size);
+}
+
+static void cleanup(void)
+{
+ if (fd > 0)
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = do_test,
+ .needs_tmpdir = 1,
+ .tcnt = ARRAY_SIZE(tcases),
+ .tags = (struct tst_tag[]) {
+ {"linux-git", "7e7757876f25"},
+ {}
+ },
+};
diff --git a/testcases/kernel/syscalls/msync/msync01.c b/testcases/kernel/syscalls/msync/msync01.c
index 3a5a48ee5..3c57ebb99 100644
--- a/testcases/kernel/syscalls/msync/msync01.c
+++ b/testcases/kernel/syscalls/msync/msync01.c
@@ -25,7 +25,7 @@
* of, or all of a mapped region.
*
* Expected Result:
- * msync() should succeed with a return value of 0, and succesfully
+ * msync() should succeed with a return value of 0, and successfully
* synchronize the memory region. Data read from mapped region should be
* the same as the initialized data.
*
diff --git a/testcases/kernel/syscalls/munlock/munlock01.c b/testcases/kernel/syscalls/munlock/munlock01.c
index 8a52f032d..31d749e66 100644
--- a/testcases/kernel/syscalls/munlock/munlock01.c
+++ b/testcases/kernel/syscalls/munlock/munlock01.c
@@ -1,162 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) Wipro Technologies Ltd, 2002. 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * AUTHOR: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
*/
-/**************************************************************************
- *
- * TEST IDENTIFIER : munlock01
- *
- * EXECUTED BY : root / superuser
- *
- * TEST TITLE : Basic test for munlock(2)
- *
- * TEST CASE TOTAL : 4
- *
- * AUTHOR : Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * DESCRIPTION
- * This is a Phase I test for the munlock(2) system call.
- * It is intended to provide a limited exposure of the system call.
- *
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise, Issue a PASS message.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- * USAGE: <for command-line>
- * munlock01 [-c n] [-e] [-i n] [-I x] [-p x] [-t]
- * where, -c n : Run n copies concurrently
- * -e : Turn on errno logging.
- * -h : Show this help screen
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -p : Pause for SIGUSR1 before starting
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * RESTRICTIONS
- * Must be root/superuser to run it.
- *****************************************************************************/
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include "test.h"
-void setup();
-void setup1(int);
-void cleanup();
+/*\
+ * [Description]
+ *
+ * Test munlock with various valid addresses and lengths.
+ */
-char *TCID = "munlock01";
-int TST_TOTAL = 4;
+#include <stdlib.h>
+#include "tst_test.h"
-void *addr1;
+static void *addr;
-struct test_case_t {
- void **addr;
+static struct tcase {
+ char *msg;
int len;
- void (*setupfunc) ();
-} TC[] = {
- {
- &addr1, 1, setup1}, {
- &addr1, 1024, setup1}, {
- &addr1, 1024 * 1024, setup1}, {
- &addr1, 1024 * 1024 * 10, setup1}
+} tcases[] = {
+ {"munlock 1 byte", 1},
+ {"munlock 1024 bytes", 1024},
+ {"munlock 1024 * 1024 bytes", 1024 * 1024},
+ {"munlock 1024 * 1024 * 10 bytes", 1024 * 1024 * 10}
};
-int main(int ac, char **av)
-{
- int lc, i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- /* check looping state */
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++) {
-
- if (TC[i].setupfunc != NULL)
- TC[i].setupfunc(i);
-
- TEST(munlock(*(TC[i].addr), TC[i].len));
-
- /* check return code */
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL | TTERRNO,
- "mlock(%p, %d) Failed with "
- "return=%ld", TC[i].addr, TC[i].len,
- TEST_RETURN);
- } else {
- tst_resm(TPASS, "test %d passed length = %d",
- i, TC[i].len);
- }
- }
- }
-
- /* cleanup and exit */
- cleanup();
-
- tst_exit();
-}
-
-void setup1(int i)
+static void verify_munlock(unsigned int i)
{
- addr1 = malloc(TC[i].len);
- if (addr1 == NULL)
- tst_brkm(TFAIL, cleanup, "malloc failed");
- TEST(mlock(*(TC[i].addr), TC[i].len));
-
- /* check return code */
- if (TEST_RETURN == -1) {
- tst_brkm(TFAIL | TTERRNO, cleanup,
- "mlock(%p, %d) Failed with return=%ld", TC[i].addr,
- TC[i].len, TEST_RETURN);
- }
+ struct tcase *tc = &tcases[i];
+
+ tst_res(TINFO, "%s", tc->msg);
+ addr = SAFE_MALLOC(tc->len);
+ SAFE_MLOCK(addr, tc->len);
+ TST_EXP_PASS(munlock(addr, tc->len), "munlock(%p, %d)", addr, tc->len);
+ free(addr);
+ addr = NULL;
}
-/* setup() - performs all ONE TIME setup for this test. */
-void setup(void)
+static void cleanup(void)
{
- tst_require_root();
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ if (addr)
+ free(addr);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .needs_root = 1,
+ .test = verify_munlock,
+ .tcnt = ARRAY_SIZE(tcases),
+ .cleanup = cleanup,
+};
diff --git a/testcases/kernel/syscalls/munlock/munlock02.c b/testcases/kernel/syscalls/munlock/munlock02.c
index 75906a1df..f51c3d21f 100644
--- a/testcases/kernel/syscalls/munlock/munlock02.c
+++ b/testcases/kernel/syscalls/munlock/munlock02.c
@@ -1,198 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) Wipro Technologies Ltd, 2002. 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * AUTHOR: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
*/
-/**************************************************************************
- *
- * TEST IDENTIFIER : munlock02
- *
- * EXECUTED BY : root / superuser
- *
- * TEST TITLE : Test for checking basic error conditions for
- * munlock(2)
- *
- * TEST CASE TOTAL : 2
- *
- * AUTHOR : Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * DESCRIPTION
- * Check for basic errors returned by munlock(2) system call.
- *
- * Verify that munlock(2) returns -1 and sets errno to
- *
- * 1) ENOMEM - Some of the specified address range does not correspond to
- * mapped pages in the address space of the process.
- *
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Do necessary setup for each test.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise, Issue a PASS message.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
+
+/*\
+ * [Description]
*
- * USAGE: <for command-line>
- * munlock02 [-c n] [-e] [-i n] [-I x] [-p x] [-t]
- * where, -c n : Run n copies concurrently
- * -e : Turn on errno logging.
- * -h : Show this help screen
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -p : Pause for SIGUSR1 before starting
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
+ * Test for ENOMEM error.
*
- * RESTRICTIONS
- * Test must run as root.
- *****************************************************************************/
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <pwd.h>
-#include "test.h"
-
-void setup();
-void cleanup();
-
-char *TCID = "munlock02";
-int TST_TOTAL = 1;
-
-#define LEN 1024
-
-void *addr1;
+ * munlock(2) fails with ENOMEM if some of the specified address range
+ * does not correspond to mapped pages in the address space of the
+ * process.
+ */
-struct test_case_t {
- void *addr;
- int len;
- int error;
- char *edesc;
-} TC[] = {
- {
-NULL, 0, ENOMEM, "address range out of address space"},};
+#include <sys/mman.h>
+#include "tst_test.h"
-#if !defined(UCLINUX)
+static size_t len, pg_size;
+static void *addr;
-int main(int ac, char **av)
+static void run(void)
{
- int lc, i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- /* check looping state */
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
- for (i = 0; i < TST_TOTAL; i++) {
-#ifdef __ia64__
- TC[0].len = 8 * getpagesize();
-#endif
- TEST(munlock(TC[i].addr, TC[i].len));
-
- /* check return code */
- if (TEST_RETURN == -1) {
- if (TEST_ERRNO != TC[i].error)
- tst_brkm(TFAIL, cleanup,
- "munlock() Failed with wrong "
- "errno, expected errno=%s, "
- "got errno=%d : %s",
- TC[i].edesc, TEST_ERRNO,
- strerror(TEST_ERRNO));
- else
- tst_resm(TPASS,
- "expected failure - errno "
- "= %d : %s",
- TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_brkm(TFAIL, cleanup,
- "munlock() Failed, expected "
- "return value=-1, got %ld",
- TEST_RETURN);
- }
- }
- }
-
- /* cleanup and exit */
- cleanup();
-
- tst_exit();
+ TST_EXP_FAIL(munlock(addr, len), ENOMEM, "munlock(%p, %lu)",
+ addr, len);
}
-/* setup() - performs all ONE TIME setup for this test. */
-
-void setup(void)
+static void setup(void)
{
-
- char *address;
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TC[0].len = 8 * getpagesize();
- address = mmap(0, TC[0].len, PROT_READ | PROT_WRITE,
- MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
- if (address == MAP_FAILED)
- tst_brkm(TFAIL, cleanup, "mmap_failed");
- memset(address, 0x20, TC[0].len);
- TEST(mlock(address, TC[0].len));
-
- /* check return code */
- if (TEST_RETURN == -1) {
- tst_brkm(TFAIL | TTERRNO, cleanup,
- "mlock(%p, %d) Failed with return=%ld", address,
- TC[0].len, TEST_RETURN);
- }
- TC[0].addr = address;
+ pg_size = getpagesize();
+ len = 8 * pg_size;
+ addr = SAFE_MMAP(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ memset(addr, 0x20, len);
+ SAFE_MLOCK(addr, len);
/*
* unmap part of the area, to create the condition for ENOMEM
*/
- address += 2 * getpagesize();
- munmap(address, 4 * getpagesize());
-
- TEST_PAUSE;
-
- return;
-}
-
-#else
-
-int main(void)
-{
- tst_resm(TINFO, "test is not available on uClinux");
- tst_exit();
+ addr += 2 * pg_size;
+ SAFE_MUNMAP(addr, 4 * pg_size);
}
-#endif /* if !defined(UCLINUX) */
-
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
- return;
-}
+static struct tst_test test = {
+ .needs_root = 1,
+ .setup = setup,
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/munmap/munmap01.c b/testcases/kernel/syscalls/munmap/munmap01.c
index 2a5cfc90d..7d10c0eac 100644
--- a/testcases/kernel/syscalls/munmap/munmap01.c
+++ b/testcases/kernel/syscalls/munmap/munmap01.c
@@ -193,7 +193,7 @@ void setup(void)
/*
* map the open file 'TEMPFILE' from its beginning up to the maplength
* into the calling process's address space at the system choosen
- * with read/write permissions to the the mapped region.
+ * with read/write permissions to the mapped region.
*/
#ifdef UCLINUX
/* MAP_SHARED is not implemented on uClinux */
diff --git a/testcases/kernel/syscalls/munmap/munmap02.c b/testcases/kernel/syscalls/munmap/munmap02.c
index b43250512..cd85d9436 100644
--- a/testcases/kernel/syscalls/munmap/munmap02.c
+++ b/testcases/kernel/syscalls/munmap/munmap02.c
@@ -197,7 +197,7 @@ void setup(void)
/*
* map the open file 'TEMPFILE' from its beginning up to the maplength
* into the calling process's address space at the system choosen
- * with read/write permissions to the the mapped region.
+ * with read/write permissions to the mapped region.
*/
#ifdef UCLINUX
/* mmap() doesn't support MAP_SHARED on uClinux */
diff --git a/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at01.c b/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at01.c
index 9677b0671..6535fdf5c 100644
--- a/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at01.c
+++ b/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at01.c
@@ -72,7 +72,7 @@ static void setup(void)
dir_fd = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
SAFE_CHDIR(TEST_DIR);
SAFE_TOUCH(TEST_FILE, 0600, NULL);
- file_fd = SAFE_OPEN("foo_file", O_RDWR | O_CREAT);
+ file_fd = SAFE_OPEN("foo_file", O_RDWR | O_CREAT, 0600);
fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
}
diff --git a/testcases/kernel/syscalls/open_by_handle_at/open_by_handle_at01.c b/testcases/kernel/syscalls/open_by_handle_at/open_by_handle_at01.c
index 76be720ca..6171229f0 100644
--- a/testcases/kernel/syscalls/open_by_handle_at/open_by_handle_at01.c
+++ b/testcases/kernel/syscalls/open_by_handle_at/open_by_handle_at01.c
@@ -55,7 +55,7 @@ static void setup(void)
dir_fd = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
SAFE_CHDIR(TEST_DIR);
SAFE_TOUCH(TEST_FILE, 0600, NULL);
- file_fd = SAFE_OPEN("foo_file", O_RDWR | O_CREAT);
+ file_fd = SAFE_OPEN("foo_file", O_RDWR | O_CREAT, 0600);
f_fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
d_fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
diff --git a/testcases/kernel/syscalls/personality/personality01.c b/testcases/kernel/syscalls/personality/personality01.c
index b646e2a9b..47fb66256 100644
--- a/testcases/kernel/syscalls/personality/personality01.c
+++ b/testcases/kernel/syscalls/personality/personality01.c
@@ -1,24 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
+ * Copyright (c) 2016 Linux Test Project
* Copyright (c) International Business Machines Corp., 2001
* 03/2001 - Written by Wayne Boyer
* Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz>
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
+/*\
+ * [Description]
+ *
* Tries to set different personalities.
*
* We set the personality in a child process since it's not guaranteed that we
@@ -26,19 +17,17 @@
* bit archs.
*/
-#include "test.h"
-#include <sys/personality.h>
-
-char *TCID = "personality01";
+#include "tst_test.h"
+#include "lapi/personality.h"
#define PAIR(id) {id, #id}
struct personalities {
- unsigned long int pers;
+ unsigned long pers;
const char *name;
};
-struct personalities pers[] = {
+static struct personalities pers[] = {
PAIR(PER_LINUX),
PAIR(PER_LINUX_32BIT),
PAIR(PER_SVR4),
@@ -62,60 +51,24 @@ struct personalities pers[] = {
PAIR(PER_HPUX),
};
-int TST_TOTAL = ARRAY_SIZE(pers);
-
-static void do_child(unsigned int i)
+static void run(unsigned int i)
{
- int ret;
+ pid_t pid;
- ret = personality(pers[i].pers);
- if (ret < 0) {
- tst_resm(TFAIL | TERRNO, "personality(%s) failed", pers[i].name);
- return;
- }
+ pid = SAFE_FORK();
+ if (!pid) {
+ SAFE_PERSONALITY(pers[i].pers);
- ret = personality(0xffffffff);
+ TST_EXP_EXPR((unsigned long)SAFE_PERSONALITY(0xffffffff) == pers[i].pers,
+ "%s personality is set",
+ pers[i].name);
- if ((unsigned long)ret != pers[i].pers) {
- tst_resm(TFAIL,
- "%s: wrong personality read back %d expected %lu",
- pers[i].name, ret, pers[i].pers);
return;
}
-
- tst_resm(TPASS, "personality(%s)", pers[i].name);
-}
-
-static void verify_personality(unsigned int i)
-{
- pid_t pid;
-
- pid = tst_fork();
- switch (pid) {
- case 0:
- do_child(i);
- tst_exit();
- break;
- case -1:
- tst_brkm(TBROK | TERRNO, NULL, "fork() failed");
- break;
- default:
- tst_record_childstatus(NULL, pid);
- break;
- }
}
-int main(int ac, char **av)
-{
- int i, lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- for (i = 0; i < TST_TOTAL; i++) {
- verify_personality(i);
- }
- }
-
- tst_exit();
-}
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(pers),
+ .forks_child = 1,
+};
diff --git a/testcases/kernel/syscalls/personality/personality02.c b/testcases/kernel/syscalls/personality/personality02.c
index eb18c9951..e080284f4 100644
--- a/testcases/kernel/syscalls/personality/personality02.c
+++ b/testcases/kernel/syscalls/personality/personality02.c
@@ -1,62 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
+ * Copyright (c) 2016 Linux Test Project
* Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz>
- *
- * 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/>.
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * If personality with STICKY_TIMEOUTS is used select() timeout is not updated.
+/*\
+ * [Description]
+ *
+ * This test checks if select() timeout is not updated when personality with
+ * STICKY_TIMEOUTS is used.
*/
-#include "test.h"
-#include <sys/personality.h>
+#include "tst_test.h"
+#include "lapi/personality.h"
#include <sys/select.h>
-char *TCID = "personality02";
-int TST_TOTAL = 1;
-
#define USEC 10
-static void verify_personality(void)
+static void run(void)
{
- struct timeval tv = {.tv_sec = 0, .tv_usec = USEC};
- int ret;
+ struct timeval tv = { .tv_sec = 0, .tv_usec = USEC };
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(1, &rfds);
- personality(PER_LINUX | STICKY_TIMEOUTS);
- ret = select(2, &rfds, NULL, NULL, &tv);
- personality(PER_LINUX);
- if (ret < 0)
- tst_resm(TBROK | TERRNO, "select()");
+ SAFE_PERSONALITY(PER_LINUX | STICKY_TIMEOUTS);
- if (tv.tv_usec != USEC)
- tst_resm(TFAIL, "Timeout was modified");
- else
- tst_resm(TPASS, "Timeout wasn't modified");
-}
-
-int main(int ac, char **av)
-{
- int lc;
+ TEST(select(2, &rfds, NULL, NULL, &tv));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "select() error");
- tst_parse_opts(ac, av, NULL, NULL);
+ SAFE_PERSONALITY(PER_LINUX);
- for (lc = 0; TEST_LOOPING(lc); lc++)
- verify_personality();
-
- tst_exit();
+ TST_EXP_EQ_LI(tv.tv_usec, USEC);
}
+
+static struct tst_test test = {
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/pipe/.gitignore b/testcases/kernel/syscalls/pipe/.gitignore
index 23e7186a6..774d73205 100644
--- a/testcases/kernel/syscalls/pipe/.gitignore
+++ b/testcases/kernel/syscalls/pipe/.gitignore
@@ -11,3 +11,4 @@
/pipe11
/pipe12
/pipe13
+/pipe14
diff --git a/testcases/kernel/syscalls/pipe/pipe03.c b/testcases/kernel/syscalls/pipe/pipe03.c
index 89c0911c1..d20867b2b 100644
--- a/testcases/kernel/syscalls/pipe/pipe03.c
+++ b/testcases/kernel/syscalls/pipe/pipe03.c
@@ -1,51 +1,42 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2002
+ * Copyright (c) 2003-2023 Linux Test Project
*/
-/*
- * Make sure that writing to the read end of a pipe and reading from
- * the write end of a pipe both fail.
+/*\
+ * [Description]
+ *
+ * Verify that, an attempt to write to the read end of a pipe fails with EBADF
+ * and an attempt to read from the write end of a pipe also fails with EBADF.
*/
-#include <unistd.h>
-#include <errno.h>
#include "tst_test.h"
static int fd[2];
static void verify_pipe(void)
{
- char buf[2];
-
- TEST(pipe(fd));
- if (TST_RET == -1) {
- tst_res(TFAIL | TTERRNO, "pipe() failed unexpectedly");
- return;
- }
-
- TEST(write(fd[0], "A", 1));
- if (TST_RET == -1 && errno == EBADF) {
- tst_res(TPASS | TTERRNO, "expected failure writing "
- "to read end of pipe");
- } else {
- tst_res(TFAIL | TTERRNO, "unexpected failure writing "
- "to read end of pipe");
- }
-
- TEST(read(fd[1], buf, 1));
- if (TST_RET == -1 && errno == EBADF) {
- tst_res(TPASS | TTERRNO, "expected failure reading "
- "from write end of pipe");
- } else {
- tst_res(TFAIL | TTERRNO, "unexpected failure reading "
- "from write end of pipe");
- }
+ char buf[] = "abcdef";
+
+ SAFE_PIPE(fd);
+
+ TST_EXP_FAIL2(write(fd[0], "A", 1), EBADF);
+ TST_EXP_FAIL2(read(fd[1], buf, 1), EBADF);
SAFE_CLOSE(fd[0]);
SAFE_CLOSE(fd[1]);
}
+static void cleanup(void)
+{
+ if (fd[0] > 0)
+ SAFE_CLOSE(fd[0]);
+ if (fd[1] > 0)
+ SAFE_CLOSE(fd[1]);
+}
+
static struct tst_test test = {
.test_all = verify_pipe,
+ .cleanup = cleanup
};
diff --git a/testcases/kernel/syscalls/pipe/pipe06.c b/testcases/kernel/syscalls/pipe/pipe06.c
index d83765632..0c6bc03bd 100644
--- a/testcases/kernel/syscalls/pipe/pipe06.c
+++ b/testcases/kernel/syscalls/pipe/pipe06.c
@@ -1,119 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) Linux Test Project, 2002-2015
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * NAME
- * pipe06.c
- *
- * DESCRIPTION
- * Check what happens when the system runs out of pipes.
- *
- * ALGORITHM
- * Issue enough pipe calls to run the system out of pipes.
- * Check that we get EMFILE.
+/*\
+ * [Description]
*
- * USAGE: <for command-line>
- * pipe06 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * None
+ * Verify that, pipe(2) syscall fails with errno EMFILE when
+ * limit on the number of open file descriptors has been reached.
*/
-#include <fcntl.h>
-#include <errno.h>
-#include "test.h"
-char *TCID = "pipe06";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include <stdlib.h>
-int pipe_ret, pipes[2];
-void setup(void);
-void cleanup(void);
+static int fds[2];
+static int *opened_fds, num_opened_fds;
-int main(int ac, char **av)
+static void setup(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- /* reset tst_count in case we are looping */
- tst_count = 0;
+ int max_fds;
- TEST(pipe(pipes));
+ max_fds = getdtablesize();
+ tst_res(TINFO, "getdtablesize() = %d", max_fds);
+ opened_fds = SAFE_MALLOC(max_fds * sizeof(int));
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "call succeeded unexpectedly");
- }
-
- if (TEST_ERRNO != EMFILE) {
- tst_resm(TFAIL | TTERRNO, "pipe failed unexpectedly");
- } else {
- tst_resm(TPASS, "failed with EMFILE");
- }
-
- }
- cleanup();
- tst_exit();
+ do {
+ SAFE_PIPE(fds);
+ opened_fds[num_opened_fds++] = fds[0];
+ opened_fds[num_opened_fds++] = fds[1];
+ } while (fds[1] < max_fds - 2);
+ tst_res(TINFO, "Number of fds opened by pipe calls: %d", num_opened_fds);
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
-void setup(void)
+static void run(void)
{
- int i, numb_fds;
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- numb_fds = getdtablesize();
-
- for (i = 0; i < numb_fds; i++) {
- pipe_ret = pipe(pipes);
- if (pipe_ret < 0) {
- if (errno != EMFILE) {
- tst_brkm(TBROK | TTERRNO, cleanup,
- "didn't get EMFILE");
- }
- break;
- }
- }
+ TST_EXP_FAIL(pipe(fds), EMFILE);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
+ for (int i = 0; i < num_opened_fds; i++)
+ SAFE_CLOSE(opened_fds[i]);
+
+ if (opened_fds)
+ free(opened_fds);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run
+};
diff --git a/testcases/kernel/syscalls/pipe/pipe07.c b/testcases/kernel/syscalls/pipe/pipe07.c
index 55bb9f419..8098007c2 100644
--- a/testcases/kernel/syscalls/pipe/pipe07.c
+++ b/testcases/kernel/syscalls/pipe/pipe07.c
@@ -1,176 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2002
- * Ported by Paul Larson
+ * Ported by Paul Larson
* Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test the ability of pipe to open the maximum even number of file
- * descriptors permitted (or (maxfds - 3)/2 pipes)
+/*\
+ * [Description]
*
- * ALGORITHM
- * 1. record file descriptors open prior to test run
- * 2. open pipes until EMFILE is returned
- * 3. check to see that the number of pipes opened is (maxfds - 3) / 2
- * 4. close all fds in range 0, maximal fd that were not open prior to
- * the test execution
+ * Verify that, pipe(2) syscall can open the maximum number of
+ * file descriptors permitted.
*/
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <dirent.h>
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "pipe07";
-int TST_TOTAL = 1;
-
-/* used to record file descriptors open at the test start */
-static int rec_fds[128];
-static int rec_fds_max;
-static void record_open_fds(void);
-static void close_test_fds(int max_fd);
+#include "tst_test.h"
+#include <stdlib.h>
-static void setup(void);
-static void cleanup(void);
+static int *opened_fds, *pipe_fds;
+static int num_pipe_fds, exp_num_pipes;
-int main(int ac, char **av)
+static int record_open_fds(void)
{
- int lc;
- int min, ret;
- int npipes;
- int pipes[2], max_fd = 0;
-
- tst_parse_opts(ac, av, NULL, NULL);
+ DIR *dir;
+ struct dirent *ent;
+ int fd;
+ int num_opened_fds = 0;
+ int arr_size = 0;
- setup();
+ dir = SAFE_OPENDIR("/proc/self/fd");
- min = getdtablesize() - rec_fds_max;
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
+ while ((ent = SAFE_READDIR(dir))) {
+ if (!strcmp(ent->d_name, ".") ||
+ !strcmp(ent->d_name, ".."))
+ continue;
+ fd = atoi(ent->d_name);
- for (npipes = 0;; npipes++) {
- ret = pipe(pipes);
- if (ret < 0) {
- if (errno != EMFILE) {
- tst_brkm(TFAIL, cleanup,
- "got unexpected error - %d",
- errno);
- }
- break;
- }
+ if (fd == dirfd(dir))
+ continue;
- max_fd = MAX(pipes[0], max_fd);
- max_fd = MAX(pipes[1], max_fd);
+ if (num_opened_fds >= arr_size) {
+ arr_size = MAX(1, arr_size * 2);
+ opened_fds = SAFE_REALLOC(opened_fds, arr_size * sizeof(int));
}
-
- if (npipes == (min / 2))
- tst_resm(TPASS, "Opened %d pipes", npipes);
- else
- tst_resm(TFAIL, "Unable to open maxfds/2 pipes");
-
- close_test_fds(max_fd);
- max_fd = 0;
+ opened_fds[num_opened_fds++] = fd;
}
- cleanup();
- tst_exit();
+ SAFE_CLOSEDIR(dir);
+
+ return num_opened_fds;
}
static void setup(void)
{
- tst_sig(FORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
+ int max_fds;
+
+ max_fds = getdtablesize();
+ tst_res(TINFO, "getdtablesize() = %d", max_fds);
+ pipe_fds = SAFE_MALLOC(max_fds * sizeof(int));
- record_open_fds();
+ exp_num_pipes = (max_fds - record_open_fds()) / 2 * 2;
+ tst_res(TINFO, "expected max fds to be opened by pipe(): %d", exp_num_pipes);
}
-static void record_open_fds(void)
+static void run(void)
{
- DIR *dir = opendir("/proc/self/fd");
- int dir_fd, fd;
- struct dirent *file;
-
- if (dir == NULL)
- tst_brkm(TBROK | TERRNO, cleanup, "opendir()");
-
- dir_fd = dirfd(dir);
+ int fds[2];
- if (dir_fd == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "dirfd()");
-
- errno = 0;
-
- while ((file = readdir(dir))) {
- if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, ".."))
- continue;
-
- fd = atoi(file->d_name);
-
- if (fd == dir_fd)
- continue;
-
- if (rec_fds_max >= (int)ARRAY_SIZE(rec_fds)) {
- tst_brkm(TBROK, cleanup,
- "Too much file descriptors open");
+ do {
+ TEST(pipe(fds));
+ if (!TST_RET) {
+ pipe_fds[num_pipe_fds++] = fds[0];
+ pipe_fds[num_pipe_fds++] = fds[1];
}
+ } while (!TST_RET);
- rec_fds[rec_fds_max++] = fd;
- }
-
- if (errno)
- tst_brkm(TBROK | TERRNO, cleanup, "readdir()");
+ TST_EXP_EQ_LI(errno, EMFILE);
+ TST_EXP_EQ_LI(exp_num_pipes, num_pipe_fds);
- closedir(dir);
+ for (int i = 0; i < num_pipe_fds; i++)
+ SAFE_CLOSE(pipe_fds[i]);
- tst_resm(TINFO, "Found %u files open", rec_fds_max);
+ num_pipe_fds = 0;
}
-static int not_recorded(int fd)
+static void cleanup(void)
{
- int i;
+ for (int i = 0; i < num_pipe_fds; i++)
+ if (pipe_fds[i] > 0)
+ SAFE_CLOSE(pipe_fds[i]);
- for (i = 0; i < rec_fds_max; i++)
- if (fd == rec_fds[i])
- return 0;
+ if (pipe_fds)
+ free(pipe_fds);
- return 1;
+ if (opened_fds)
+ free(opened_fds);
}
-static void close_test_fds(int max_fd)
-{
- int i;
-
- for (i = 0; i <= max_fd; i++) {
- if (not_recorded(i)) {
- if (close(i)) {
- if (errno == EBADF)
- continue;
- tst_resm(TWARN | TERRNO, "close(%i)", i);
- }
- }
- }
-}
-
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run
+};
diff --git a/testcases/kernel/syscalls/pipe/pipe08.c b/testcases/kernel/syscalls/pipe/pipe08.c
index 173ec788a..28088cf61 100644
--- a/testcases/kernel/syscalls/pipe/pipe08.c
+++ b/testcases/kernel/syscalls/pipe/pipe08.c
@@ -1,137 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * NAME
- * pipe08.c
- *
- * DESCRIPTION
- * Check that a SIGPIPE signal is generated when a write is
- * attempted on an empty pipe.
- *
- * ALGORITHM
- * 1. Write to a pipe after closing the read side.
- * 2. Check for the signal SIGPIPE to be received.
+/*\
+ * [Description]
*
- * USAGE: <for command-line>
- * pipe08 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * USAGE
- * pipe08
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * None
+ * Verify that, on any attempt to write to a pipe which is closed for
+ * reading will generate a SIGPIPE signal and write will fail with
+ * EPIPE errno.
*/
-#include <errno.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include "test.h"
-char *TCID = "pipe08";
-int TST_TOTAL = 1;
+#include "tst_test.h"
-void setup(void);
-void cleanup(void);
-void sighandler(int);
+static int pipefd[2];
+static volatile int sigpipe_cnt;
-int main(int ac, char **av)
+static void sighandler(int sig)
{
- int lc;
-
- int pipefd[2]; /* fds for pipe read/write */
- char wrbuf[BUFSIZ];
- int written, length;
- int close_stat; /* exit status of close(read fd) */
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
- TEST(pipe(pipefd));
+ if (sig == SIGPIPE)
+ sigpipe_cnt++;
+}
- if (TEST_RETURN != 0) {
- tst_resm(TFAIL, "call failed unexpectedly");
- continue;
- }
+static void run(void)
+{
+ char wrbuf[] = "abcdefghijklmnopqrstuvwxyz";
- if ((close_stat = close(pipefd[0])) == -1) {
- tst_brkm(TBROK, cleanup, "close of read side failed");
- }
+ sigpipe_cnt = 0;
- strcpy(wrbuf, "abcdefghijklmnopqrstuvwxyz\0");
- length = strlen(wrbuf);
+ SAFE_PIPE(pipefd);
+ SAFE_CLOSE(pipefd[0]);
- /*
- * the SIGPIPE signal will be caught here or else
- * the program will dump core when the signal is
- * sent
- */
- written = write(pipefd[1], wrbuf, length);
- if (written > 0)
- tst_brkm(TBROK, cleanup, "write succeeded unexpectedly");
- }
- cleanup();
- tst_exit();
+ TST_EXP_FAIL2_SILENT(write(pipefd[1], wrbuf, sizeof(wrbuf)), EPIPE);
+ TST_EXP_EQ_LI(sigpipe_cnt, 1);
+ SAFE_CLOSE(pipefd[1]);
}
-/*
- * sighandler - catch signals and look for SIGPIPE
- */
-void sighandler(int sig)
+static void setup(void)
{
- if (sig != SIGPIPE)
- tst_resm(TFAIL, "expected SIGPIPE, got %d", sig);
- else
- tst_resm(TPASS, "got expected SIGPIPE signal");
+ SAFE_SIGNAL(SIGPIPE, sighandler);
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
-void setup(void)
+static void cleanup(void)
{
-
- tst_sig(NOFORK, sighandler, cleanup);
-
- TEST_PAUSE;
+ if (pipefd[0] > 0)
+ SAFE_CLOSE(pipefd[0]);
+ if (pipefd[1] > 0)
+ SAFE_CLOSE(pipefd[1]);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .cleanup = cleanup
+};
diff --git a/testcases/kernel/syscalls/pipe/pipe10.c b/testcases/kernel/syscalls/pipe/pipe10.c
index 48f722e3e..018e653da 100644
--- a/testcases/kernel/syscalls/pipe/pipe10.c
+++ b/testcases/kernel/syscalls/pipe/pipe10.c
@@ -1,164 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * NAME
- * pipe10.c
- *
- * DESCRIPTION
- * Check that parent can open a pipe and have a child read from it
- *
- * ALGORITHM
- * Parent opens pipe, child reads. Passes if child can read all the
- * characters written by the parent.
- *
- * USAGE: <for command-line>
- * pipe10 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+/*\
+ * [Description]
*
- * RESTRICTIONS
- * None
+ * Verify that, when a parent process opens a pipe, a child process can
+ * read from it.
*/
-#include <errno.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <string.h>
-#include "test.h"
-char *TCID = "pipe10";
-int TST_TOTAL = 1;
+#include <stdio.h>
+#include "tst_test.h"
-void setup(void);
-void cleanup(void);
+static int fds[2];
-ssize_t do_read(int fd, void *buf, size_t count)
+static void run(void)
{
- ssize_t n;
-
- do {
- n = read(fd, buf, count);
- } while (n < 0 && errno == EINTR);
-
- return n;
-}
-
-int main(int ac, char **av)
-{
- int lc;
-
- int fd[2]; /* fds for pipe read/write */
- char wrbuf[BUFSIZ], rebuf[BUFSIZ];
- int red, written; /* no of chars read and */
- /* written to pipe */
- int length, greater, forkstat;
- int retval = 0, status, e_code;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
+ int wr_cnt, rd_cnt;
+ char wrbuf[] = "abcdefghijklmnopqrstuvwxyz";
+ char rdbuf[BUFSIZ];
- /* reset tst_count in case we are looping */
- tst_count = 0;
+ SAFE_PIPE(fds);
+ wr_cnt = SAFE_WRITE(SAFE_WRITE_ALL, fds[1], wrbuf, sizeof(wrbuf));
- TEST(pipe(fd));
-
- if (TEST_RETURN == -1) {
- retval = 1;
- tst_resm(TFAIL, "pipe creation failed");
- continue;
- }
-
- strcpy(wrbuf, "abcdefghijklmnopqrstuvwxyz");
- length = strlen(wrbuf) + 1;
-
- written = write(fd[1], wrbuf, length);
-
- /* did write write at least some chars */
- if ((written < 0) || (written > length)) {
- tst_brkm(TBROK, cleanup, "write to pipe failed");
- }
-
- forkstat = FORK_OR_VFORK();
-
- if (forkstat == -1) {
- tst_brkm(TBROK, cleanup, "fork() failed");
- }
-
- if (forkstat == 0) { /* child */
- red = do_read(fd[0], rebuf, written);
-
- /* did read , get at least some chars */
- if ((red < 0) || (red > written)) {
- tst_brkm(TBROK, cleanup, "read pipe failed");
- }
-
- greater = strcmp(rebuf, wrbuf);
-
- /* are the strings written and read equal */
- if (greater == 0) {
- tst_resm(TPASS, "functionality is correct");
- } else {
- retval = 1;
- tst_resm(TFAIL, "read & write strings do "
- "not match");
- }
- exit(retval);
- } else { /* parent */
- /* wait for the child to finish */
- wait(&status);
- /* make sure the child returned a good exit status */
- e_code = status >> 8;
- if (e_code != 0) {
- tst_resm(TFAIL, "Failures reported above");
- }
- }
+ if (!SAFE_FORK()) {
+ rd_cnt = SAFE_READ(1, fds[0], rdbuf, wr_cnt);
+ TST_EXP_EQ_LU(wr_cnt, rd_cnt);
}
- cleanup();
- tst_exit();
+ tst_reap_children();
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(fds[1]);
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
-void setup(void)
+static void cleanup(void)
{
+ if (fds[0] > 0)
+ SAFE_CLOSE(fds[0]);
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ if (fds[1] > 0)
+ SAFE_CLOSE(fds[1]);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+ .cleanup = cleanup
+};
diff --git a/testcases/kernel/syscalls/pipe/pipe14.c b/testcases/kernel/syscalls/pipe/pipe14.c
new file mode 100644
index 000000000..2d2969d82
--- /dev/null
+++ b/testcases/kernel/syscalls/pipe/pipe14.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that, if the write end of a pipe is closed, then a process reading
+ * from the pipe will see end-of-file (i.e., read() returns 0) once it has
+ * read all remaining data in the pipe.
+ */
+
+#include "tst_test.h"
+
+static int fds[2];
+
+static void run(void)
+{
+ char wrbuf[] = "abcdefghijklmnopqrstuvwxyz";
+ char rdbuf[30];
+
+ memset(rdbuf, 0, sizeof(rdbuf));
+ SAFE_PIPE(fds);
+
+ SAFE_WRITE(SAFE_WRITE_ALL, fds[1], wrbuf, sizeof(wrbuf));
+ SAFE_CLOSE(fds[1]);
+
+ SAFE_READ(0, fds[0], rdbuf, sizeof(wrbuf));
+
+ TST_EXP_VAL(SAFE_READ(0, fds[0], rdbuf, 1), 0);
+ SAFE_CLOSE(fds[0]);
+}
+
+static void cleanup(void)
+{
+ if (fds[0] > 0)
+ SAFE_CLOSE(fds[0]);
+ if (fds[1] > 0)
+ SAFE_CLOSE(fds[1]);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .cleanup = cleanup
+};
diff --git a/testcases/kernel/syscalls/prctl/prctl04.c b/testcases/kernel/syscalls/prctl/prctl04.c
index f6e1f0fea..8b135d611 100644
--- a/testcases/kernel/syscalls/prctl/prctl04.c
+++ b/testcases/kernel/syscalls/prctl/prctl04.c
@@ -45,6 +45,7 @@
static const struct sock_filter strict_filter[] = {
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
+ BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_waitid, 7, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_rt_sigprocmask, 6, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_close, 5, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_exit, 4, 0),
diff --git a/testcases/kernel/syscalls/preadv2/preadv203.c b/testcases/kernel/syscalls/preadv2/preadv203.c
index 25c6e1c2e..c87deb674 100644
--- a/testcases/kernel/syscalls/preadv2/preadv203.c
+++ b/testcases/kernel/syscalls/preadv2/preadv203.c
@@ -159,7 +159,7 @@ static void *writer_thread(void *unused)
while (!stop) {
int fd = fds[random() % FILES];
- for (j = 0; j < CHUNKS; j++) {
+ for (j = 0; j < CHUNKS && !stop; j++) {
memset(buf, '0' + j, sizeof(buf));
off_t off = CHUNK_SZ * j;
diff --git a/testcases/kernel/syscalls/process_madvise/.gitignore b/testcases/kernel/syscalls/process_madvise/.gitignore
new file mode 100644
index 000000000..93d2640f7
--- /dev/null
+++ b/testcases/kernel/syscalls/process_madvise/.gitignore
@@ -0,0 +1 @@
+/process_madvise01
diff --git a/testcases/kernel/syscalls/paging/Makefile b/testcases/kernel/syscalls/process_madvise/Makefile
index 044619fb8..ad5b66061 100644
--- a/testcases/kernel/syscalls/paging/Makefile
+++ b/testcases/kernel/syscalls/process_madvise/Makefile
@@ -1,8 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (c) International Business Machines Corp., 2001
+# Copyright (C) 2023 Linux Test Project, Inc.
top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/process_madvise/process_madvise.h b/testcases/kernel/syscalls/process_madvise/process_madvise.h
new file mode 100644
index 000000000..5b227ada0
--- /dev/null
+++ b/testcases/kernel/syscalls/process_madvise/process_madvise.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+#ifndef PROCESS_MADVISE_H__
+#define PROCESS_MADVISE_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "tst_safe_stdio.h"
+
+struct addr_mapping {
+ int size;
+ int rss;
+ int pss;
+ int shared_clean;
+ int shared_dirty;
+ int private_clean;
+ int private_dirty;
+ int referenced;
+ int anonymous;
+ int anon_huge_pages;
+ int shmem_huge_pages;
+ int shmem_pmd_mapped;
+ int swap;
+ int kernel_page_size;
+ int mmu_page_size;
+ int locked;
+ int protection_key;
+};
+
+static inline void read_address_mapping(unsigned long address, struct addr_mapping *mapping)
+{
+ FILE *f;
+ int found = 0;
+ char label[BUFSIZ];
+ char line[BUFSIZ];
+ char smaps[BUFSIZ];
+ char ptr_str[BUFSIZ];
+ int value;
+
+ snprintf(smaps, BUFSIZ, "/proc/%i/smaps", getpid());
+ snprintf(ptr_str, BUFSIZ, "%lx", address);
+
+ f = SAFE_FOPEN(smaps, "r");
+
+ while (fgets(line, BUFSIZ, f) != NULL) {
+ if (strncmp(ptr_str, line, strlen(ptr_str)) == 0)
+ found = 1;
+
+ if (!found)
+ continue;
+
+ if (found && strncmp(line, "VmFlags", 7) == 0)
+ break;
+
+ if (sscanf(line, "%31[^:]: %d", label, &value) > 0) {
+ if (strcmp(label, "Size") == 0)
+ mapping->size = value;
+ else if (strcmp(label, "Rss") == 0)
+ mapping->rss = value;
+ else if (strcmp(label, "Pss") == 0)
+ mapping->pss = value;
+ else if (strcmp(label, "Shared_Clean") == 0)
+ mapping->shared_clean = value;
+ else if (strcmp(label, "Shared_Dirty") == 0)
+ mapping->shared_dirty = value;
+ else if (strcmp(label, "Private_Clean") == 0)
+ mapping->private_clean = value;
+ else if (strcmp(label, "Private_Dirty") == 0)
+ mapping->private_dirty = value;
+ else if (strcmp(label, "Referenced") == 0)
+ mapping->referenced = value;
+ else if (strcmp(label, "Anonymous") == 0)
+ mapping->anonymous = value;
+ else if (strcmp(label, "AnonHugePages") == 0)
+ mapping->anon_huge_pages = value;
+ else if (strcmp(label, "ShmemHugePages") == 0)
+ mapping->shmem_huge_pages = value;
+ else if (strcmp(label, "ShmemPmdMapped") == 0)
+ mapping->shmem_pmd_mapped = value;
+ else if (strcmp(label, "Swap") == 0)
+ mapping->swap = value;
+ else if (strcmp(label, "KernelPageSize") == 0)
+ mapping->kernel_page_size = value;
+ else if (strcmp(label, "MMUPageSize") == 0)
+ mapping->mmu_page_size = value;
+ else if (strcmp(label, "Locked") == 0)
+ mapping->locked = value;
+ else if (strcmp(label, "ProtectionKey") == 0)
+ mapping->protection_key = value;
+ }
+ }
+
+ SAFE_FCLOSE(f);
+}
+
+#endif
diff --git a/testcases/kernel/syscalls/process_madvise/process_madvise01.c b/testcases/kernel/syscalls/process_madvise/process_madvise01.c
new file mode 100644
index 000000000..0fd3c1ef4
--- /dev/null
+++ b/testcases/kernel/syscalls/process_madvise/process_madvise01.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Allocate anonymous memory pages inside child and reclaim it with
+ * MADV_PAGEOUT. Then check if memory pages have been swapped out by looking
+ * at smaps information.
+ *
+ * The advice might be ignored for some pages in the range when it is
+ * not applicable, so test passes if swap memory increases after
+ * reclaiming memory with MADV_PAGEOUT.
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/mman.h>
+#include "tst_test.h"
+#include "lapi/mmap.h"
+#include "lapi/syscalls.h"
+#include "process_madvise.h"
+
+#define MEM_CHILD (1 * TST_MB)
+
+static void **data_ptr;
+
+static void child_alloc(void)
+{
+ char data[MEM_CHILD];
+ struct addr_mapping map_before;
+ struct addr_mapping map_after;
+
+ memset(data, 'a', MEM_CHILD);
+
+ tst_res(TINFO, "Allocate memory: %d bytes", MEM_CHILD);
+
+ *data_ptr = SAFE_MMAP(NULL, MEM_CHILD,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+
+ memset(*data_ptr, 'a', MEM_CHILD);
+
+ memset(&map_before, 0, sizeof(struct addr_mapping));
+ read_address_mapping((unsigned long)*data_ptr, &map_before);
+
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+ memset(&map_after, 0, sizeof(struct addr_mapping));
+ read_address_mapping((unsigned long)*data_ptr, &map_after);
+
+ if (memcmp(*data_ptr, data, MEM_CHILD) != 0) {
+ tst_res(TFAIL, "Dirty memory after reclaiming it");
+ return;
+ }
+
+ SAFE_MUNMAP(*data_ptr, MEM_CHILD);
+ *data_ptr = NULL;
+
+ TST_EXP_EXPR(map_before.swap < map_after.swap,
+ "Most of the memory has been swapped out: %dkB out of %dkB",
+ map_after.swap - map_before.swap,
+ MEM_CHILD / TST_KB);
+}
+
+static void setup(void)
+{
+ data_ptr = SAFE_MMAP(NULL, sizeof(void *),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+static void cleanup(void)
+{
+ if (*data_ptr)
+ SAFE_MUNMAP(*data_ptr, MEM_CHILD);
+
+ if (data_ptr)
+ SAFE_MUNMAP(data_ptr, sizeof(void *));
+}
+
+static void run(void)
+{
+ int ret;
+ int pidfd;
+ pid_t pid_alloc;
+ struct iovec vec;
+
+ pid_alloc = SAFE_FORK();
+ if (!pid_alloc) {
+ child_alloc();
+ return;
+ }
+
+ TST_CHECKPOINT_WAIT(0);
+
+ tst_res(TINFO, "Reclaim memory using MADV_PAGEOUT");
+
+ pidfd = SAFE_PIDFD_OPEN(pid_alloc, 0);
+
+ vec.iov_base = *data_ptr;
+ vec.iov_len = MEM_CHILD;
+
+ ret = tst_syscall(__NR_process_madvise, pidfd, &vec, 1UL,
+ MADV_PAGEOUT, 0UL);
+
+ if (ret == -1)
+ tst_brk(TBROK | TERRNO, "process_madvise failed");
+
+ if (ret != MEM_CHILD)
+ tst_brk(TBROK, "process_madvise reclaimed only %d bytes", ret);
+
+ TST_CHECKPOINT_WAKE(0);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .forks_child = 1,
+ .min_kver = "5.10",
+ .needs_checkpoints = 1,
+ .needs_root = 1,
+ .min_swap_avail = MEM_CHILD / TST_MB,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_SWAP=y",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/quotactl/quotactl08.c b/testcases/kernel/syscalls/quotactl/quotactl08.c
index da1d62a32..0fabb51a5 100644
--- a/testcases/kernel/syscalls/quotactl/quotactl08.c
+++ b/testcases/kernel/syscalls/quotactl/quotactl08.c
@@ -28,6 +28,7 @@
* - turn off quota with Q_QUOTAOFF flag for group
*
* It is similar to quotactl01.c, only two difference
+ *
* - use new quotactl_fd syscalls if supports
* - quota file hidden in filesystem
*
diff --git a/testcases/kernel/syscalls/readahead/readahead02.c b/testcases/kernel/syscalls/readahead/readahead02.c
index 7acf4bb18..dc03c5931 100644
--- a/testcases/kernel/syscalls/readahead/readahead02.c
+++ b/testcases/kernel/syscalls/readahead/readahead02.c
@@ -318,6 +318,19 @@ static void test_readahead(unsigned int n)
tst_res(TCONF, "Page cache on your system is too small "
"to hold whole testfile.");
}
+
+ /*
+ * The time consuming of readahead quite depending on the platform IO
+ * speed, sometime test timeout when the default max_runtime is used up.
+ *
+ * readahead02.c:221: TINFO: Test #2: POSIX_FADV_WILLNEED on file
+ * readahead02.c:285: TINFO: read_testfile(0) took: 26317623 usec
+ * readahead02.c:286: TINFO: read_testfile(1) took: 26101484 usec
+ *
+ * Here raise the maximum runtime dynamically.
+ */
+ if ((tc+1)->readahead)
+ tst_set_max_runtime(test.max_runtime + (usec + usec_ra) / 1000000);
}
@@ -352,7 +365,7 @@ static void setup_readahead_length(void)
/* raise bdi limit as much as kernel allows */
ra_new_limit = testfile_size / 1024;
while (ra_new_limit > pagesize / 1024) {
- FILE_PRINTF(sys_bdi_ra_path, "%d", ra_new_limit);
+ SAFE_FILE_PRINTF(sys_bdi_ra_path, "%d", ra_new_limit);
SAFE_FILE_SCANF(sys_bdi_ra_path, "%d", &ra_limit);
if (ra_limit == ra_new_limit) {
diff --git a/testcases/kernel/syscalls/readlinkat/readlinkat01.c b/testcases/kernel/syscalls/readlinkat/readlinkat01.c
index 985890ebe..b1214c3ae 100644
--- a/testcases/kernel/syscalls/readlinkat/readlinkat01.c
+++ b/testcases/kernel/syscalls/readlinkat/readlinkat01.c
@@ -1,143 +1,103 @@
-/******************************************************************************
- *
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
* Copyright (c) International Business Machines Corp., 2006
- * Author: Yi Yang <yyangcdl@cn.ibm.com>
* Copyright (c) Cyril Hrubis 2014 <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: Yi Yang <yyangcdl@cn.ibm.com>
+ */
+
+/*\
+ * [Description]
*
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * This test case will verify basic function of readlinkat
- * added by kernel 2.6.16 or up.
+ * Check the basic functionality of the readlinkat() system call.
*
- *****************************************************************************/
+ * - readlinkat() passes if dirfd is directory file descriptor
+ * and the pathname is relative.
+ * - readlinkat() passes if the pathname is abspath, then dirfd
+ * is ignored.
+ * - readlinkat() passes if dirfd is the special value AT_FDCWD
+ * and the pathname is relative.
+ * - readlinkat() passes if pathname is an empty string, in which
+ * case the call operates on the symbolic link referred to by dirfd.
+ */
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <fcntl.h>
#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include "test.h"
-#include "safe_macros.h"
-#include "lapi/readlinkat.h"
-
-static void setup(void);
-static void cleanup(void);
+#include <stdio.h>
+#include "tst_test.h"
+#include "lapi/fcntl.h"
-char *TCID = "readlinkat01";
+#define TEST_FILE "readlink_file"
+#define TEST_SYMLINK "readlink_symlink"
-static int dir_fd, fd;
-static int fd_invalid = 100;
+static int file_fd, dir_fd, dir_fd2;
static int fd_atcwd = AT_FDCWD;
-
-#define TEST_SYMLINK "readlink_symlink"
-#define TEST_FILE "readlink_file"
-
-static char abspath[1024];
-
-static struct test_case {
- int *dir_fd;
- const char *path;
- const char *exp_buf;
- int exp_ret;
- int exp_errno;
-} test_cases[] = {
- {&dir_fd, TEST_SYMLINK, TEST_FILE, sizeof(TEST_FILE)-1, 0},
- {&dir_fd, abspath, TEST_FILE, sizeof(TEST_FILE)-1, 0},
- {&fd, TEST_SYMLINK, NULL, -1, ENOTDIR},
- {&fd_invalid, TEST_SYMLINK, NULL, -1, EBADF},
- {&fd_atcwd, TEST_SYMLINK, TEST_FILE, sizeof(TEST_FILE)-1, 0},
+static const char *abspath;
+static const char *testsymlink;
+static const char *emptypath;
+
+static struct tcase {
+ int *fd;
+ const char **path;
+} tcases[] = {
+ {&dir_fd, &testsymlink},
+ {&dir_fd, &abspath},
+ {&file_fd, &abspath},
+ {&fd_atcwd, &abspath},
+ {&fd_atcwd, &testsymlink},
+ {&dir_fd2, &emptypath},
};
-int TST_TOTAL = ARRAY_SIZE(test_cases);
-
-static void verify_readlinkat(struct test_case *test)
+static void verify_readlinkat(unsigned int i)
{
char buf[1024];
+ struct tcase *tc = &tcases[i];
memset(buf, 0, sizeof(buf));
- TEST(readlinkat(*test->dir_fd, test->path, buf, sizeof(buf)));
-
- if (TEST_RETURN != test->exp_ret) {
- tst_resm(TFAIL | TTERRNO,
- "readlinkat() returned %ld, expected %d",
- TEST_RETURN, test->exp_ret);
- return;
- }
-
- if (TEST_ERRNO != test->exp_errno) {
- tst_resm(TFAIL | TTERRNO,
- "readlinkat() returned %ld, expected %d",
- TEST_RETURN, test->exp_ret);
- return;
- }
-
- if (test->exp_ret > 0 && strcmp(test->exp_buf, buf)) {
- tst_resm(TFAIL, "Unexpected buffer have '%s', expected '%s'",
- buf, test->exp_buf);
- return;
- }
-
- tst_resm(TPASS | TTERRNO, "readlinkat() returned %ld", TEST_RETURN);
-}
-
-int main(int ac, char **av)
-{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
+ TST_EXP_POSITIVE(readlinkat(*tc->fd, *tc->path, buf, sizeof(buf)),
+ "readlinkat(%d, %s, %s, %ld)",
+ *tc->fd, *tc->path, buf, sizeof(buf));
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- for (i = 0; i < TST_TOTAL; i++)
- verify_readlinkat(&test_cases[i]);
- }
-
- cleanup();
- tst_exit();
+ if (strcmp(buf, TEST_FILE) == 0)
+ tst_res(TPASS, "The filename in buffer is correct");
+ else
+ tst_res(TFAIL, "Wrong filename in buffer '%s'", buf);
}
static void setup(void)
{
- tst_tmpdir();
char *tmpdir = tst_get_tmpdir();
- snprintf(abspath, sizeof(abspath), "%s/" TEST_SYMLINK, tmpdir);
+ abspath = tst_aprintf("%s/" TEST_SYMLINK, tmpdir);
free(tmpdir);
- fd = SAFE_OPEN(cleanup, TEST_FILE, O_CREAT, 0600);
- SAFE_SYMLINK(cleanup, TEST_FILE, TEST_SYMLINK);
- dir_fd = SAFE_OPEN(cleanup, ".", O_DIRECTORY);
-
- TEST_PAUSE;
+ file_fd = SAFE_OPEN(TEST_FILE, O_CREAT, 0600);
+ SAFE_SYMLINK(TEST_FILE, TEST_SYMLINK);
+ dir_fd = SAFE_OPEN(".", O_DIRECTORY);
+ dir_fd2 = SAFE_OPEN(TEST_SYMLINK, O_PATH | O_NOFOLLOW);
}
static void cleanup(void)
{
- if (fd > 0 && close(fd))
- tst_resm(TWARN | TERRNO, "Failed to close fd");
+ if (file_fd > -1)
+ SAFE_CLOSE(file_fd);
- if (dir_fd > 0 && close(dir_fd))
- tst_resm(TWARN | TERRNO, "Failed to close dir_fd");
+ if (dir_fd > -1)
+ SAFE_CLOSE(dir_fd);
- tst_rmdir();
+ if (dir_fd2 > -1)
+ SAFE_CLOSE(dir_fd2);
}
+
+static struct tst_test test = {
+ .test = verify_readlinkat,
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .bufs = (struct tst_buffers []) {
+ {&testsymlink, .str = TEST_SYMLINK},
+ {&emptypath, .str = ""},
+ {},
+ },
+ .tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/readlinkat/readlinkat02.c b/testcases/kernel/syscalls/readlinkat/readlinkat02.c
index d30c1917a..64afb898f 100644
--- a/testcases/kernel/syscalls/readlinkat/readlinkat02.c
+++ b/testcases/kernel/syscalls/readlinkat/readlinkat02.c
@@ -1,122 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014 Fujitsu Ltd.
+ * Copyright (c) Linux Test Project, 2003-2023
* Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
+ */
+
+/*\
+ * [Description]
*
- * 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.
+ * - readlinkat() fails with EINVAL if the bufsiz is 0.
*
- * 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 Library General Public License for more details.
+ * - readlinkat() fails with EINVAL if the named file is not a symbolic link.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * - readlinkat() fails with ENOTDIR if the component of the path prefix is
+ * not a directory.
*
- */
-/*
- * Test Description:
- * Verify that,
- * 1. bufsiz is 0, EINVAL should be returned.
- * 2. The named file is not a symbolic link, EINVAL should be returned.
- * 3. The component of the path prefix is not a directory, ENOTDIR should be
- * returned.
- * 4. pathname is relative and dirfd is a file descriptor referring to a file
- * other than a directory, ENOTDIR should be returned.
+ * - readlinkat() fails with ENOTDIR if the pathname is relative and
+ * dirfd is a file descriptor referring to a file other than a directory.
+ *
+ * - readlinkat() fails with EBADF if the file descriptor is invalid.
+ *
+ * - readlinkat() fails with ENOENT when the pathname does not exists.
*/
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "test.h"
-#include "safe_macros.h"
-#include "lapi/readlinkat.h"
-#include "lapi/syscalls.h"
+#include "tst_test.h"
#define TEST_FILE "test_file"
#define SYMLINK_FILE "symlink_file"
#define BUFF_SIZE 256
static int file_fd, dir_fd;
+static int fd_invalid = -1;
-static struct test_case_t {
- int *dirfd;
+static struct tcase {
+ int *fd;
const char *pathname;
size_t bufsiz;
int exp_errno;
-} test_cases[] = {
+} tcases[] = {
{&dir_fd, SYMLINK_FILE, 0, EINVAL},
{&dir_fd, TEST_FILE, BUFF_SIZE, EINVAL},
{&file_fd, SYMLINK_FILE, BUFF_SIZE, ENOTDIR},
{&dir_fd, "test_file/test_file", BUFF_SIZE, ENOTDIR},
+ {&fd_invalid, SYMLINK_FILE, BUFF_SIZE, EBADF},
+ {&dir_fd, "does_not_exists", BUFF_SIZE, ENOENT},
};
-char *TCID = "readlinkat02";
-int TST_TOTAL = ARRAY_SIZE(test_cases);
-static void setup(void);
-static void cleanup(void);
-static void readlinkat_verify(const struct test_case_t *);
-
-int main(int argc, char **argv)
+static void verify_readlinkat(unsigned int i)
{
- int i, lc;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
+ char buf[BUFF_SIZE];
+ struct tcase *tc = &tcases[i];
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- for (i = 0; i < TST_TOTAL; i++)
- readlinkat_verify(&test_cases[i]);
- }
+ memset(buf, 0, sizeof(buf));
- cleanup();
- tst_exit();
+ TST_EXP_FAIL(readlinkat(*tc->fd, tc->pathname, buf, tc->bufsiz),
+ tc->exp_errno, "readlinkat(%d, %s, NULL, %ld)",
+ *tc->fd, tc->pathname, tc->bufsiz);
}
static void setup(void)
{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ dir_fd = SAFE_OPEN(".", O_RDONLY);
- TEST_PAUSE;
+ file_fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT, 0644);
- tst_tmpdir();
-
- dir_fd = SAFE_OPEN(cleanup, "./", O_RDONLY);
-
- file_fd = SAFE_OPEN(cleanup, TEST_FILE, O_RDWR | O_CREAT, 0644);
-
- SAFE_SYMLINK(cleanup, TEST_FILE, SYMLINK_FILE);
-}
-
-static void readlinkat_verify(const struct test_case_t *test)
-{
- char buf[BUFF_SIZE];
- TEST(readlinkat(*test->dirfd, test->pathname, buf, test->bufsiz));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "readlinkat succeeded unexpectedly");
- return;
- }
-
- if (TEST_ERRNO == test->exp_errno) {
- tst_resm(TPASS | TTERRNO, "readlinkat failed as expected");
- } else {
- tst_resm(TFAIL | TTERRNO,
- "readlinkat failed unexpectedly; expected: %d - %s",
- test->exp_errno, strerror(test->exp_errno));
- }
+ SAFE_SYMLINK(TEST_FILE, SYMLINK_FILE);
}
static void cleanup(void)
{
- close(dir_fd);
- close(file_fd);
+ if (file_fd > -1)
+ SAFE_CLOSE(file_fd);
- tst_rmdir();
+ if (dir_fd > -1)
+ SAFE_CLOSE(dir_fd);
}
+
+static struct tst_test test = {
+ .test = verify_readlinkat,
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/recvmsg/recvmsg01.c b/testcases/kernel/syscalls/recvmsg/recvmsg01.c
index 3ce7ab027..80c1b3aa9 100644
--- a/testcases/kernel/syscalls/recvmsg/recvmsg01.c
+++ b/testcases/kernel/syscalls/recvmsg/recvmsg01.c
@@ -1,364 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2001 Wayne Boyer International Business Machines
+ * Copyright (c) Linux Test Project, 2002-2022
+ * Copyright (c) 2023 Wei Gao <wegao@suse.com>
*/
-/*
- * Test Name: recvmsg01
- *
- * Test Description:
- * Verify that recvmsg() returns the proper errno for various failure cases
- *
- * Usage: <for command-line>
- * recvmsg01 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- * None.
+/*\
+ * [Description]
*
+ * Verify that recvmsg() returns the proper errno for various failure cases.
*/
#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
+#include <stdlib.h>
#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/file.h>
-
-#include <netinet/in.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "recvmsg01";
-int testno;
-
-char buf[1024], cbuf[1024];
-int s; /* socket descriptor */
-int passed_fd = -1; /* rights-passing test descriptor */
-struct sockaddr_in sin1, from;
-struct sockaddr_un sun1;
-struct msghdr msgdat;
-struct cmsghdr *control = 0;
-int controllen = 0;
-struct iovec iov[1];
+#include "tst_test.h"
+
+#define MSG "from recvmsg01 server"
+#define BUF_SIZE 1024
+#define CONTROL_LEN (128 * 1024)
+
+static char recv_buf[BUF_SIZE], cbuf[BUF_SIZE];
+static int sock;
+static struct sockaddr_in sin1, from;
+static struct sockaddr_un sun1;
+static struct msghdr msgdat;
+static struct cmsghdr *control;
+static int controllen;
+static struct iovec iov[1];
static int sfd; /* shared between do_child and start_server */
static int ufd; /* shared between do_child and start_server */
-
-void setup(void);
-void setup0(void);
-void setup1(void);
-void setup2(void);
-void setup3(void);
-void setup4(void);
-void cleanup(void);
-void cleanup0(void);
-void cleanup1(void);
-void cleanup2(void);
-void do_child(void);
-
-void sender(int);
-pid_t start_server(struct sockaddr_in *, struct sockaddr_un *);
-
-struct test_case_t { /* test case structure */
- int domain; /* PF_INET, PF_UNIX, ... */
- int type; /* SOCK_STREAM, SOCK_DGRAM ... */
- int proto; /* protocol number (usually 0 = default) */
+static pid_t pid;
+static char tmpsunpath[BUF_SIZE];
+
+static void setup_all(void);
+static void setup_invalid_sock(int);
+static void setup_valid_sock(int);
+static void setup_valid_msg_control(int);
+static void setup_large_msg_control(int);
+static void cleanup_all(void);
+static void cleanup_invalid_sock(int);
+static void cleanup_close_sock(int);
+static void cleanup_reset_all(int);
+static void do_child(void);
+static pid_t start_server(struct sockaddr_in *, struct sockaddr_un *);
+
+static struct tcase {
+ int domain;
+ int type;
+ int protocol;
struct iovec *iov;
int iovcnt;
- void *buf; /* recv data buffer */
- int buflen; /* recv buffer length */
+ void *recv_buf;
+ int buflen;
struct msghdr *msg;
- unsigned flags;
- struct sockaddr *from; /* from address */
- int fromlen; /* from address value/result buffer length */
- int retval; /* syscall return value */
- int experrno; /* expected errno */
- void (*setup) (void);
- void (*cleanup) (void);
+ unsigned int flags;
+ struct sockaddr *from;
+ int fromlen;
+ int exp_errno;
+ void (*setup)(int n);
+ void (*cleanup)(int n);
char *desc;
-} tdat[] = {
-/* 1 */
- {
- PF_INET, SOCK_STREAM, 0, iov, 1, buf, sizeof(buf), &msgdat, 0,
- (struct sockaddr *)&from, sizeof(from),
- -1, EBADF, setup0, cleanup0, "bad file descriptor"}
- ,
-/* 2 */
+} tcases[] = {
{
- 0, 0, 0, iov, 1, (void *)buf, sizeof(buf), &msgdat, 0,
- (struct sockaddr *)&from, sizeof(from),
- -1, ENOTSOCK, setup0, cleanup0, "invalid socket"}
- ,
-/* 3 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .exp_errno = EBADF,
+ .setup = setup_invalid_sock,
+ .cleanup = cleanup_invalid_sock,
+ .desc = "bad file descriptor",
+ },
{
- PF_INET, SOCK_STREAM, 0, iov, 1, (void *)buf, sizeof(buf),
- &msgdat, 0, (struct sockaddr *)-1, sizeof(from), 0,
- ENOTSOCK, setup1, cleanup1, "invalid socket buffer"}
- ,
-/* 4 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = (void *)recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .exp_errno = ENOTSOCK,
+ .setup = setup_invalid_sock,
+ .cleanup = cleanup_invalid_sock,
+ .desc = "invalid socket",
+ },
{
- PF_INET, SOCK_STREAM, 0, iov, 1, (void *)buf, sizeof(buf),
- &msgdat, -1, (struct sockaddr *)&from, -1, -1,
- EINVAL, setup1, cleanup1, "invalid socket length"},
-/* 5 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = (void *)recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .flags = -1,
+ .from = (struct sockaddr *)&from,
+ .fromlen = -1,
+ .exp_errno = EINVAL,
+ .setup = setup_valid_sock,
+ .cleanup = cleanup_close_sock,
+ .desc = "invalid socket length",
+ },
{
- PF_INET, SOCK_STREAM, 0, iov, 1, (void *)-1, sizeof(buf),
- &msgdat, 0, (struct sockaddr *)&from, sizeof(from),
- -1, EFAULT, setup1, cleanup1, "invalid recv buffer"}
- ,
-/* 6 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = (void *)-1,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .exp_errno = EFAULT,
+ .setup = setup_valid_sock,
+ .cleanup = cleanup_close_sock,
+ .desc = "invalid recv buffer",
+ },
{
- PF_INET, SOCK_STREAM, 0, 0, 1, (void *)buf, sizeof(buf),
- &msgdat, 0, (struct sockaddr *)&from, sizeof(from),
- -1, EFAULT, setup1, cleanup1, "invalid iovec buffer"}
- ,
-/* 7 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iovcnt = 1,
+ .recv_buf = recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .exp_errno = EFAULT,
+ .setup = setup_valid_sock,
+ .cleanup = cleanup_close_sock,
+ .desc = "invalid iovec buffer",
+ },
{
- PF_INET, SOCK_STREAM, 0, iov, -1, (void *)buf, sizeof(buf),
- &msgdat, 0, (struct sockaddr *)&from, sizeof(from),
- -1, EMSGSIZE, setup1, cleanup1, "invalid iovec count"}
- ,
-/* 8 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = -1,
+ .recv_buf = recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .exp_errno = EMSGSIZE,
+ .setup = setup_valid_sock,
+ .cleanup = cleanup_close_sock,
+ .desc = "invalid iovec count",
+ },
{
- PF_UNIX, SOCK_STREAM, 0, iov, 1, (void *)buf, sizeof(buf),
- &msgdat, 0, (struct sockaddr *)&from, sizeof(from),
- 0, 0, setup2, cleanup2, "rights reception"}
- ,
-/* 9 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .setup = setup_valid_msg_control,
+ .cleanup = cleanup_reset_all,
+ .desc = "permission reception",
+ },
{
- PF_INET, SOCK_STREAM, 0, iov, 1, (void *)buf, sizeof(buf),
- &msgdat, MSG_OOB, (struct sockaddr *)&from,
- sizeof(from), -1, EINVAL, setup1, cleanup1,
- "invalid MSG_OOB flag set"}
- ,
-/* 10 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .flags = MSG_OOB,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .exp_errno = EINVAL,
+ .setup = setup_valid_sock,
+ .cleanup = cleanup_close_sock,
+ .desc = "invalid MSG_OOB flag set",
+ },
{
- PF_INET, SOCK_STREAM, 0, iov, 1, (void *)buf, sizeof(buf),
- &msgdat, MSG_ERRQUEUE, (struct sockaddr *)&from,
- sizeof(from), -1, EAGAIN, setup1, cleanup1,
- "invalid MSG_ERRQUEUE flag set"}
- ,
-/* 11 */
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .flags = MSG_ERRQUEUE,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .exp_errno = EAGAIN,
+ .setup = setup_valid_sock,
+ .cleanup = cleanup_close_sock,
+ .desc = "invalid MSG_ERRQUEUE flag set",
+ },
{
- PF_UNIX, SOCK_STREAM, 0, iov, 1, (void *)buf, sizeof(buf),
- &msgdat, 0, (struct sockaddr *)&from, sizeof(from),
- 0, EINVAL, setup3, cleanup2, "invalid cmsg length"}
- ,
-/* 12 */
- {
- PF_UNIX, SOCK_STREAM, 0, iov, 1, (void *)buf, sizeof(buf),
- &msgdat, 0, (struct sockaddr *)&from, sizeof(from),
- 0, 0, setup4, cleanup2, "large cmesg length"}
-,};
-
-int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]);
-
-#ifdef UCLINUX
-static char *argv0;
-#endif
-
-int main(int argc, char *argv[])
+ .domain = PF_INET,
+ .type = SOCK_STREAM,
+ .iov = iov,
+ .iovcnt = 1,
+ .recv_buf = recv_buf,
+ .buflen = sizeof(recv_buf),
+ .msg = &msgdat,
+ .from = (struct sockaddr *)&from,
+ .fromlen = sizeof(from),
+ .setup = setup_large_msg_control,
+ .cleanup = cleanup_reset_all,
+ .desc = "large cmesg length",
+ },
+
+};
+
+static void run(unsigned int n)
{
- int lc;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-#ifdef UCLINUX
- argv0 = argv[0];
- maybe_run_child(&do_child, "dd", &sfd, &ufd);
-#endif
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); ++lc) {
- tst_count = 0;
- for (testno = 0; testno < TST_TOTAL; ++testno) {
- if ((tst_kvercmp(3, 17, 0) < 0)
- && (tdat[testno].flags & MSG_ERRQUEUE)
- && (tdat[testno].type & SOCK_STREAM)) {
- tst_resm(TCONF, "skip MSG_ERRQUEUE test, "
- "it's supported from 3.17");
- continue;
- }
+ struct tcase *tc = &tcases[n];
+ int ret = tc->exp_errno ? -1 : 0;
- tdat[testno].setup();
-
- /* setup common to all tests */
- iov[0].iov_base = tdat[testno].buf;
- iov[0].iov_len = tdat[testno].buflen;
- msgdat.msg_name = tdat[testno].from;
- msgdat.msg_namelen = tdat[testno].fromlen;
- msgdat.msg_iov = tdat[testno].iov;
- msgdat.msg_iovlen = tdat[testno].iovcnt;
- msgdat.msg_control = control;
- msgdat.msg_controllen = controllen;
- msgdat.msg_flags = 0;
-
- TEST(recvmsg(s, tdat[testno].msg, tdat[testno].flags));
- if (TEST_RETURN >= 0)
- TEST_RETURN = 0; /* all nonzero equal here */
- if (TEST_RETURN != tdat[testno].retval ||
- (TEST_RETURN < 0 &&
- TEST_ERRNO != tdat[testno].experrno)) {
- tst_resm(TFAIL, "%s ; returned"
- " %ld (expected %d), errno %d (expected"
- " %d)", tdat[testno].desc,
- TEST_RETURN, tdat[testno].retval,
- TEST_ERRNO, tdat[testno].experrno);
- } else {
- tst_resm(TPASS, "%s successful",
- tdat[testno].desc);
- }
- tdat[testno].cleanup();
- }
+ if ((tst_kvercmp(3, 17, 0) < 0)
+ && (tc->flags & MSG_ERRQUEUE)
+ && (tc->type & SOCK_STREAM)) {
+ tst_res(TCONF, "MSG_ERRQUEUE requires kernel >= 3.17");
+ return;
+ }
+
+ setup_all();
+ tc->setup(n);
+
+ iov[0].iov_base = tc->recv_buf;
+ iov[0].iov_len = tc->buflen;
+ msgdat.msg_name = tc->from;
+ msgdat.msg_namelen = tc->fromlen;
+ msgdat.msg_iov = tc->iov;
+ msgdat.msg_iovlen = tc->iovcnt;
+ msgdat.msg_control = control;
+ msgdat.msg_controllen = controllen;
+ msgdat.msg_flags = 0;
+
+ TEST(recvmsg(sock, tc->msg, tc->flags));
+ if (TST_RET >= 0)
+ TST_RET = 0;
+
+ if (TST_RET != ret) {
+ tst_res(TFAIL | TTERRNO, "%s: expected %d, returned %ld",
+ tc->desc, ret, TST_RET);
+ } else if (TST_ERR != tc->exp_errno) {
+ tst_res(TFAIL | TTERRNO,
+ "%s: expected %s",
+ tc->desc, tst_strerrno(tc->exp_errno));
+ } else {
+ tst_res(TPASS, "%s passed", tc->desc);
}
- cleanup();
- tst_exit();
+ tc->cleanup(n);
+ cleanup_all();
}
-pid_t pid;
-char tmpsunpath[1024];
-void setup(void)
+static void setup_all(void)
{
int tfd;
- TEST_PAUSE;
- tst_tmpdir();
+ sun1.sun_family = AF_UNIX;
+
(void)strcpy(tmpsunpath, "udsockXXXXXX");
tfd = mkstemp(tmpsunpath);
- close(tfd);
- unlink(tmpsunpath);
- sun1.sun_family = AF_UNIX;
+ SAFE_CLOSE(tfd);
+ SAFE_UNLINK(tmpsunpath);
(void)strcpy(sun1.sun_path, tmpsunpath);
-
- signal(SIGPIPE, SIG_IGN);
-
+ SAFE_SIGNAL(SIGPIPE, SIG_IGN);
pid = start_server(&sin1, &sun1);
}
-void cleanup(void)
+static void cleanup_all(void)
{
if (pid > 0) {
(void)kill(pid, SIGKILL); /* kill server */
wait(NULL);
}
- if (tmpsunpath[0] != '\0')
- (void)unlink(tmpsunpath);
- tst_rmdir();
+ if (tmpsunpath[0] != '\0')
+ (void)SAFE_UNLINK(tmpsunpath);
}
-void setup0(void)
+static void setup_invalid_sock(int n)
{
- if (tdat[testno].experrno == EBADF)
- s = 400; /* anything not an open file */
- else if ((s = open("/dev/null", O_WRONLY)) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "open(/dev/null) failed");
+ if (tcases[n].exp_errno == EBADF)
+ sock = 400; /* anything not an open file */
+ else
+ sock = SAFE_OPEN("/dev/null", O_WRONLY);
}
-void cleanup0(void)
+static void cleanup_invalid_sock(int n)
{
- s = -1;
+ if (tcases[n].exp_errno == EBADF)
+ sock = -1;
+ else
+ SAFE_CLOSE(sock);
}
-void setup1(void)
+static void setup_valid_sock(int n)
{
fd_set rdfds;
struct timeval timeout;
- int n;
-
- s = SAFE_SOCKET(cleanup, tdat[testno].domain, tdat[testno].type,
- tdat[testno].proto);
- if (tdat[testno].type == SOCK_STREAM) {
- if (tdat[testno].domain == PF_INET) {
- SAFE_CONNECT(cleanup, s, (struct sockaddr *)&sin1,
- sizeof(sin1));
+
+ sock = SAFE_SOCKET(tcases[n].domain, tcases[n].type, tcases[n].protocol);
+
+ if (tcases[n].type == SOCK_STREAM) {
+ if (tcases[n].domain == PF_INET) {
+ SAFE_CONNECT(sock, (struct sockaddr *)&sin1, sizeof(sin1));
/* Wait for something to be readable, else we won't detect EFAULT on recv */
FD_ZERO(&rdfds);
- FD_SET(s, &rdfds);
+ FD_SET(sock, &rdfds);
timeout.tv_sec = 2;
timeout.tv_usec = 0;
- n = select(s + 1, &rdfds, 0, 0, &timeout);
- if (n != 1 || !FD_ISSET(s, &rdfds))
- tst_brkm(TBROK, cleanup,
- "client setup1 failed - no message ready in 2 sec");
- } else if (tdat[testno].domain == PF_UNIX) {
- SAFE_CONNECT(cleanup, s, (struct sockaddr *)&sun1,
- sizeof(sun1));
+ n = select(sock + 1, &rdfds, 0, 0, &timeout);
+
+ if (n != 1 || !FD_ISSET(sock, &rdfds))
+ tst_brk(TBROK, "no message ready in %d sec", (int)timeout.tv_sec);
+
+ } else if (tcases[n].domain == PF_UNIX) {
+ SAFE_CONNECT(sock, (struct sockaddr *)&sun1, sizeof(sun1));
}
}
}
-void setup2(void)
+static void setup_valid_msg_control(int n)
{
- setup1();
- if (write(s, "R", 1) < 0)
- tst_brkm(TBROK | TERRNO, cleanup, "test setup failed: write:");
+ setup_valid_sock(n);
+ SAFE_SEND(1, sock, "R", 1, 0);
control = (struct cmsghdr *)cbuf;
controllen = control->cmsg_len = sizeof(cbuf);
}
-void setup3(void)
+static void setup_large_msg_control(int n)
{
- setup2();
- controllen = sizeof(struct cmsghdr) - 1;
+ setup_valid_msg_control(n);
+ controllen = CONTROL_LEN;
}
-void setup4(void)
+static void cleanup_close_sock(int n LTP_ATTRIBUTE_UNUSED)
{
- setup2();
- controllen = 128 * 1024;
+ SAFE_CLOSE(sock);
}
-void cleanup1(void)
+static void cleanup_reset_all(int n LTP_ATTRIBUTE_UNUSED)
{
- (void)close(s);
- close(ufd);
- close(sfd);
- s = -1;
-}
+ SAFE_CLOSE(sock);
-void cleanup2(void)
-{
- close(ufd);
- close(sfd);
- (void)close(s);
- s = -1;
-
- if (passed_fd >= 0)
- (void)close(passed_fd);
- passed_fd = -1;
control = 0;
controllen = 0;
}
@@ -373,63 +365,70 @@ pid_t start_server(struct sockaddr_in *ssin, struct sockaddr_un *ssun)
ssin->sin_addr.s_addr = INADDR_ANY;
/* set up inet socket */
- sfd = socket(PF_INET, SOCK_STREAM, 0);
- if (sfd < 0) {
- tst_brkm(TBROK | TERRNO, cleanup, "server socket failed");
- return -1;
- }
- if (bind(sfd, (struct sockaddr *)ssin, sizeof(*ssin)) < 0) {
- tst_brkm(TBROK | TERRNO, cleanup, "server bind failed");
- return -1;
- }
- if (listen(sfd, 10) < 0) {
- tst_brkm(TBROK | TERRNO, cleanup, "server listen failed");
- return -1;
- }
- SAFE_GETSOCKNAME(cleanup, sfd, (struct sockaddr *)ssin, &slen);
+ sfd = SAFE_SOCKET(PF_INET, SOCK_STREAM, 0);
+ SAFE_BIND(sfd, (struct sockaddr *)ssin, sizeof(*ssin));
+ SAFE_LISTEN(sfd, 10);
+ SAFE_GETSOCKNAME(sfd, (struct sockaddr *)ssin, &slen);
/* set up UNIX-domain socket */
- ufd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (ufd < 0) {
- tst_brkm(TBROK | TERRNO, cleanup, "server UD socket failed");
- return -1;
- }
- if (bind(ufd, (struct sockaddr *)ssun, sizeof(*ssun))) {
- tst_brkm(TBROK | TERRNO, cleanup, "server UD bind failed");
- return -1;
- }
- if (listen(ufd, 10) < 0) {
- tst_brkm(TBROK | TERRNO, cleanup, "server UD listen failed");
- return -1;
- }
+ ufd = SAFE_SOCKET(PF_UNIX, SOCK_STREAM, 0);
+ SAFE_BIND(ufd, (struct sockaddr *)ssun, sizeof(*ssun));
+ SAFE_LISTEN(ufd, 10);
- switch ((pid = FORK_OR_VFORK())) {
- case 0: /* child */
-#ifdef UCLINUX
- if (self_exec(argv0, "dd", sfd, ufd) < 0)
- tst_brkm(TBROK | TERRNO, cleanup,
- "server self_exec failed");
-#else
+ pid = SAFE_FORK();
+ if (!pid) {
do_child();
-#endif
- break;
- case -1:
- tst_brkm(TBROK | TERRNO, cleanup, "server fork failed");
- /* fall through */
- default: /* parent */
- (void)close(sfd);
- (void)close(ufd);
- return pid;
+ exit(1);
}
- exit(1);
+
+ SAFE_CLOSE(sfd);
+ SAFE_CLOSE(ufd);
+
+ return pid;
+}
+
+/* for permission test */
+static void sender(int fd)
+{
+ struct msghdr mh = {};
+ struct cmsghdr *control;
+ char tmpfn[BUF_SIZE] = "";
+ char snd_cbuf[BUF_SIZE] = "";
+ int tfd;
+
+ (void)strcpy(tmpfn, "smtXXXXXX");
+ tfd = mkstemp(tmpfn);
+ if (tfd < 0)
+ return;
+
+ /* set up cmsghdr */
+ control = (struct cmsghdr *)snd_cbuf;
+ control->cmsg_len = sizeof(struct cmsghdr) + 4;
+ control->cmsg_level = SOL_SOCKET;
+ control->cmsg_type = SCM_RIGHTS;
+ *(int *)CMSG_DATA(control) = tfd;
+
+ /* set up msghdr */
+ iov[0].iov_base = MSG;
+ iov[0].iov_len = sizeof(MSG);
+ mh.msg_iov = iov;
+ mh.msg_iovlen = 1;
+ mh.msg_flags = 0;
+ mh.msg_control = control;
+ mh.msg_controllen = control->cmsg_len;
+
+ /* do it */
+ SAFE_SENDMSG(sizeof(MSG), fd, &mh, 0);
+ SAFE_CLOSE(tfd);
+ (void)SAFE_UNLINK(tmpfn);
}
-void do_child(void)
+static void do_child(void)
{
struct sockaddr_in fsin;
struct sockaddr_un fsun;
fd_set afds, rfds;
- int nfds, cc, fd;
+ int nfds, fd;
FD_ZERO(&afds);
FD_SET(sfd, &afds);
@@ -455,19 +454,19 @@ void do_child(void)
int newfd;
fromlen = sizeof(fsin);
- newfd = accept(sfd, (struct sockaddr *)&fsin, &fromlen);
+ newfd = SAFE_ACCEPT(sfd, (struct sockaddr *)&fsin, &fromlen);
if (newfd >= 0) {
FD_SET(newfd, &afds);
nfds = MAX(nfds, newfd + 1);
/* send something back */
- (void)write(newfd, "hoser\n", 6);
+ SAFE_SEND(1, newfd, "hi", 2, 0);
}
}
if (FD_ISSET(ufd, &rfds)) {
int newfd;
fromlen = sizeof(fsun);
- newfd = accept(ufd, (struct sockaddr *)&fsun, &fromlen);
+ newfd = SAFE_ACCEPT(ufd, (struct sockaddr *)&fsun, &fromlen);
if (newfd >= 0) {
FD_SET(newfd, &afds);
nfds = MAX(nfds, newfd + 1);
@@ -475,55 +474,22 @@ void do_child(void)
}
for (fd = 0; fd < nfds; ++fd)
if (fd != sfd && fd != ufd && FD_ISSET(fd, &rfds)) {
- char rbuf[1024];
+ char rbuf[BUF_SIZE];
- cc = read(fd, rbuf, sizeof(rbuf));
- if (cc && rbuf[0] == 'R')
+ TEST(read(fd, rbuf, sizeof(rbuf)));
+ if (TST_RET > 0 && rbuf[0] == 'R')
sender(fd);
- if (cc == 0 || (cc < 0 && errno != EINTR)) {
- (void)close(fd);
+ if (TST_RET == 0 || (TST_RET < 0 && TST_ERR != EINTR)) {
+ close(fd);
FD_CLR(fd, &afds);
}
}
}
}
-#define TM "from recvmsg01 server"
-
-/* special for rights-passing test */
-void sender(int fd)
-{
- struct msghdr mh;
- struct cmsghdr *control;
- char tmpfn[1024], snd_cbuf[1024];
- int tfd;
-
- (void)strcpy(tmpfn, "smtXXXXXX");
- tfd = mkstemp(tmpfn);
- if (tfd < 0)
- return;
-
- memset(&mh, 0x00, sizeof(mh));
-
- /* set up cmsghdr */
- control = (struct cmsghdr *)snd_cbuf;
- memset(control, 0x00, sizeof(struct cmsghdr));
- control->cmsg_len = sizeof(struct cmsghdr) + 4;
- control->cmsg_level = SOL_SOCKET;
- control->cmsg_type = SCM_RIGHTS;
- *(int *)CMSG_DATA(control) = tfd;
-
- /* set up msghdr */
- iov[0].iov_base = TM;
- iov[0].iov_len = sizeof(TM);
- mh.msg_iov = iov;
- mh.msg_iovlen = 1;
- mh.msg_flags = 0;
- mh.msg_control = control;
- mh.msg_controllen = control->cmsg_len;
-
- /* do it */
- (void)sendmsg(fd, &mh, 0);
- (void)close(tfd);
- (void)unlink(tmpfn);
-}
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .forks_child = 1,
+ .needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/sbrk/sbrk01.c b/testcases/kernel/syscalls/sbrk/sbrk01.c
index ce26b1503..c99fb0106 100644
--- a/testcases/kernel/syscalls/sbrk/sbrk01.c
+++ b/testcases/kernel/syscalls/sbrk/sbrk01.c
@@ -1,111 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- * AUTHOR : William Roske
- * CO-PILOT : Dave Fenner
- *
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
- */
-/*
- * DESCRIPTION
- * 1.) test sbrk(8192) should return successfully.
- * 2.) test sbrk(-8192) should return successfully.
+ * AUTHOR : William Roske, CO-PILOT : Dave Fenner
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-
-#include "test.h"
+/*\
+ * [Description]
+ *
+ * Verify that sbrk() successfully increments or decrements the program's
+ * data break.
+ */
-char *TCID = "sbrk01";
+#include "tst_test.h"
-static struct test_case_t {
+static struct tcase {
long increment;
-} test_cases[] = {
+} tcases[] = {
+ {0},
{8192},
- {-8192},
+ {-8192}
};
-static void setup(void);
-static void sbrk_verify(const struct test_case_t *);
-static void cleanup(void);
-
-int TST_TOTAL = ARRAY_SIZE(test_cases);
-
-int main(int ac, char **av)
+static void run(unsigned int i)
{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
+ struct tcase *tc = &tcases[i];
- setup();
+ TESTPTR(sbrk(tc->increment));
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++)
- sbrk_verify(&test_cases[i]);
- }
-
- cleanup();
- tst_exit();
-
-}
-
-static void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ if (TST_RET_PTR == (void *) -1)
+ tst_res(TFAIL | TTERRNO, "sbrk(%ld) failed", tc->increment);
+ else
+ tst_res(TPASS, "sbrk(%ld) returned %p", tc->increment, TST_RET_PTR);
}
-static void sbrk_verify(const struct test_case_t *test)
-{
- void *tret;
-
- tret = sbrk(test->increment);
- TEST_ERRNO = errno;
-
- if (tret == (void *)-1) {
- tst_resm(TFAIL | TTERRNO, "sbrk - Increase by %ld bytes failed",
- test->increment);
- } else {
- tst_resm(TPASS, "sbrk - Increase by %ld bytes returned %p",
- test->increment, tret);
- }
-}
-
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases)
+};
diff --git a/testcases/kernel/syscalls/sbrk/sbrk02.c b/testcases/kernel/syscalls/sbrk/sbrk02.c
index 84744ef90..7fccc4d3a 100644
--- a/testcases/kernel/syscalls/sbrk/sbrk02.c
+++ b/testcases/kernel/syscalls/sbrk/sbrk02.c
@@ -1,101 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2014 Fujitsu Ltd.
* Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
- *
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * DESCRIPTION
- * Check sbrk() with error condition that should produce ENOMEM.
- */
-
-#include <errno.h>
-#include <unistd.h>
-#include "test.h"
-#define INC 16*1024*1024
+/*\
+ * [Description]
+ *
+ * Verify that sbrk() on failure sets errno to ENOMEM.
+ */
-char *TCID = "sbrk02";
-int TST_TOTAL = 1;
-static void setup(void);
-static void sbrk_verify(void);
-static void cleanup(void);
+#include "tst_test.h"
+#define INC (16*1024*1024)
static long increment = INC;
-int main(int argc, char *argv[])
+static void run(void)
{
- int lc;
- int i;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
+ TESTPTR(sbrk(increment));
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- for (i = 0; i < TST_TOTAL; i++)
- sbrk_verify();
+ if (TST_RET_PTR != (void *)-1) {
+ tst_res(TFAIL, "sbrk(%ld) unexpectedly passed and returned %p, "
+ "expected (void *)-1 with errno=%d",
+ increment, TST_RET_PTR, ENOMEM);
+ return;
}
- cleanup();
- tst_exit();
+ if (TST_ERR == ENOMEM)
+ tst_res(TPASS | TTERRNO, "sbrk(%ld) failed as expected", increment);
+ else
+ tst_res(TFAIL | TTERRNO, "sbrk(%ld) failed but unexpected errno, "
+ "expected errno=%d - %s",
+ increment, ENOMEM, strerror(ENOMEM));
}
static void setup(void)
{
void *ret = NULL;
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /* call sbrk until it fails or increment overflows */
while (ret != (void *)-1 && increment > 0) {
ret = sbrk(increment);
increment += INC;
}
- tst_resm(TINFO | TERRNO, "setup() bailing inc: %ld, ret: %p, sbrk: %p",
- increment, ret, sbrk(0));
-
- errno = 0;
-}
-
-static void sbrk_verify(void)
-{
- void *tret;
-
- tret = sbrk(increment);
- TEST_ERRNO = errno;
-
- if (tret != (void *)-1) {
- tst_resm(TFAIL,
- "sbrk(%ld) returned %p, expected (void *)-1, errno=%d",
- increment, tret, ENOMEM);
- return;
- }
-
- if (TEST_ERRNO == ENOMEM) {
- tst_resm(TPASS | TTERRNO, "sbrk(%ld) failed as expected",
- increment);
- } else {
- tst_resm(TFAIL | TTERRNO,
- "sbrk(%ld) failed unexpectedly; expected: %d - %s",
- increment, ENOMEM, strerror(ENOMEM));
- }
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup
+};
diff --git a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c
index 447242159..597de4665 100644
--- a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c
+++ b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c
@@ -69,7 +69,7 @@ static void run(void)
}
if (proc_flag)
- TST_ASSERT_INT("/proc/sys/kernel/sched_rr_timeslice_ms", tst_ts_to_ms(tp));
+ TST_ASSERT_INT(PROC_SCHED_RR_TIMESLICE_MS, tst_ts_to_ms(tp));
}
static struct tst_test test = {
@@ -79,6 +79,7 @@ static struct tst_test test = {
.needs_root = 1,
.tags = (const struct tst_tag[]) {
{"linux-git", "975e155ed873"},
+ {"linux-git", "c7fcb99877f9"},
{}
}
};
diff --git a/testcases/kernel/syscalls/sendfile/sendfile04.c b/testcases/kernel/syscalls/sendfile/sendfile04.c
index 9a8ec08b9..4fa748137 100644
--- a/testcases/kernel/syscalls/sendfile/sendfile04.c
+++ b/testcases/kernel/syscalls/sendfile/sendfile04.c
@@ -14,6 +14,7 @@
* [Algorithm]
*
* Given wrong address or protected buffer as OFFSET argument to sendfile:
+ *
* - a wrong address is created by munmap a buffer allocated by mmap
* - a protected buffer is created by mmap with specifying protection
*/
diff --git a/testcases/kernel/syscalls/setgroups/.gitignore b/testcases/kernel/syscalls/setgroups/.gitignore
index 0649a3425..9de928241 100644
--- a/testcases/kernel/syscalls/setgroups/.gitignore
+++ b/testcases/kernel/syscalls/setgroups/.gitignore
@@ -4,5 +4,3 @@
/setgroups02_16
/setgroups03
/setgroups03_16
-/setgroups04
-/setgroups04_16
diff --git a/testcases/kernel/syscalls/setgroups/setgroups01.c b/testcases/kernel/syscalls/setgroups/setgroups01.c
index fed7f8e5a..9a5b77e93 100644
--- a/testcases/kernel/syscalls/setgroups/setgroups01.c
+++ b/testcases/kernel/syscalls/setgroups/setgroups01.c
@@ -1,202 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2003-2023
*
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
+ * Author: William Roske
+ * CO-PILOT: Dave Fenner
*/
-/* $Id: setgroups01.c,v 1.7 2009/11/02 13:57:18 subrata_modak Exp $ */
-/**********************************************************
- *
- * OS Test - Silicon Graphics, Inc.
- *
- * TEST IDENTIFIER : setgroups01
- *
- * EXECUTED BY : root
- *
- * TEST TITLE : Basic test for setgroups(2)
- *
- * PARENT DOCUMENT : usctpl01
- *
- * TEST CASE TOTAL : 1
- *
- * WALL CLOCK TIME : 1
- *
- * CPU TYPES : ALL
- *
- * AUTHOR : William Roske
- *
- * CO-PILOT : Dave Fenner
- *
- * DATE STARTED : 03/30/92
- *
- * INITIAL RELEASE : UNICOS 7.0
- *
- * TEST CASES
- *
- * 1.) setgroups(2) returns...(See Description)
- *
- * INPUT SPECIFICATIONS
- * The standard options for system call tests are accepted.
- * (See the parse_opts(3) man page).
- *
- * OUTPUT SPECIFICATIONS
- *$
- * DURATION
- * Terminates - with frequency and infinite modes.
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * RESOURCES
- * None
- *
- * ENVIRONMENTAL NEEDS
- * No run-time environmental needs.
- *
- * SPECIAL PROCEDURAL REQUIREMENTS
- * None
- *
- * INTERCASE DEPENDENCIES
- * None
- *
- * DETAILED DESCRIPTION
- * This is a Phase I test for the setgroups(2) system call. It is intended
- * to provide a limited exposure of the system call, for now. It
- * should/will be extended when full functional tests are written for
- * setgroups(2).
- *
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise, Issue a PASS message.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- *
- *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
-
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <grp.h>
-#include "test.h"
-
-#include "compat_16.h"
+/*\
+ * [Description]
+ *
+ * Check the basic functionality of the setgroups() system call.
+ */
-void setup();
-void cleanup();
+#include "tst_test.h"
+#include "compat_tst_16.h"
-TCID_DEFINE(setgroups01);
-int TST_TOTAL = 1;
+static int len = NGROUPS;
-int len = NGROUPS, ngrps = 0;
-GID_T list[NGROUPS];
+static GID_T list[NGROUPS];
-int main(int ac, char **av)
+static void verify_setgroups(void)
{
- int lc;
-
- /***************************************************************
- * parse standard options
- ***************************************************************/
- tst_parse_opts(ac, av, NULL, NULL);
-
- /***************************************************************
- * perform global setup for test
- ***************************************************************/
- setup();
-
- /***************************************************************
- * check looping state if -c option given
- ***************************************************************/
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call setgroups(2)
- */
- TEST(SETGROUPS(cleanup, ngrps, list));
-
- /* check return code */
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL,
- "setgroups(%d, list) Failed, errno=%d : %s",
- len, TEST_ERRNO, strerror(TEST_ERRNO));
- } else {
- tst_resm(TPASS,
- "setgroups(%d, list) returned %ld",
- len, TEST_RETURN);
- }
-
- }
-
- cleanup();
- tst_exit();
+ TST_EXP_POSITIVE(SETGROUPS(1, list), "setgroups()");
}
-/***************************************************************
- * setup() - performs all ONE TIME setup for this test.
- ***************************************************************/
-void setup(void)
+static void setup(void)
{
-
- tst_require_root();
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- ngrps = GETGROUPS(cleanup, len, list);
- if (ngrps == -1) {
- tst_brkm(TBROK, cleanup,
- "getgroups(%d, list) Failure. errno=%d : %s",
- len, errno, strerror(errno));
- }
+ len = GETGROUPS(NGROUPS, list);
+ if (len < 0)
+ tst_brk(TBROK | TERRNO, "getgroups() Failed");
}
-/***************************************************************
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- ***************************************************************/
-void cleanup(void)
-{
-
-}
+static struct tst_test test = {
+ .test_all = verify_setgroups,
+ .setup = setup,
+ .needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/setgroups/setgroups02.c b/testcases/kernel/syscalls/setgroups/setgroups02.c
index de23a4a7f..2b7f95c87 100644
--- a/testcases/kernel/syscalls/setgroups/setgroups02.c
+++ b/testcases/kernel/syscalls/setgroups/setgroups02.c
@@ -1,180 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) Linux Test Project, 2003-2023
+ * 07/2001 Ported by Wayne Boyer
*/
-/*
- * Test Name: setgroups02
- *
- * Test Description:
- * Verify that, only root process can invoke setgroups() system call to
- * set the supplementary group IDs of the process.
- *
- * Expected Result:
- * The call succeeds in setting all the supplementary group IDs of the
- * calling process. The new group should be set in the process supplemental
- * group list.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise,
- * Verify the Functionality of system call
- * if successful,
- * Issue Functionality-Pass message.
- * Otherwise,
- * Issue Functionality-Fail message.
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- * Usage: <for command-line>
- * setgroups02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- * This test should be run by 'super-user' (root) only.
+/*\
+ * [Description]
*
+ * Check that root process can setgroups() supplementary group ID and verify
+ * that getgroups() returns the previously set ID.
*/
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/param.h>
-
-#include "test.h"
-
-#include "compat_16.h"
-#define TESTUSER "nobody"
-
-TCID_DEFINE(setgroups02);
-int TST_TOTAL = 1; /* Total number of test conditions */
-GID_T groups_list[NGROUPS]; /* Array to hold gids for getgroups() */
-
-struct passwd *user_info; /* struct. to hold test user info */
-void setup(); /* setup function for the test */
-void cleanup(); /* cleanup function for the test */
-
-int main(int ac, char **av)
-{
- int lc, i;
- int gidsetsize = 1; /* only one GID, the GID of TESTUSER */
- int PASS_FLAG = 0; /* used for checking group array */
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call setgroups() to set supplimentary group IDs of
- * the calling super-user process to gid of TESTUSER.
- */
- TEST(SETGROUPS(cleanup, gidsetsize, groups_list));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL, "setgroups(%d, groups_list) Failed, "
- "errno=%d : %s", gidsetsize, TEST_ERRNO,
- strerror(TEST_ERRNO));
- continue;
- }
+#include <pwd.h>
- /*
- * Call getgroups(2) to verify that
- * setgroups(2) successfully set the
- * supp. gids of TESTUSER.
- */
- groups_list[0] = '\0';
- if (GETGROUPS(cleanup, gidsetsize, groups_list) < 0) {
- tst_brkm(TFAIL, cleanup, "getgroups() Fails, "
- "error=%d", errno);
- }
- for (i = 0; i < NGROUPS; i++) {
- if (groups_list[i] == user_info->pw_gid) {
- tst_resm(TPASS,
- "Functionality of setgroups"
- "(%d, groups_list) successful",
- gidsetsize);
- PASS_FLAG = 1;
- }
- }
- if (PASS_FLAG == 0) {
- tst_resm(TFAIL, "Supplimentary gid %d not set "
- "for the process", user_info->pw_gid);
- }
- }
+#include "tst_test.h"
+#include "compat_tst_16.h"
- cleanup();
- tst_exit();
-}
+static GID_T *groups_get, *groups_set;
-/*
- * setup() - performs all ONE TIME setup for this test.
- *
- * Make sure the test process uid is root.
- * Get the supplimentrary group id of test user from /etc/passwd file.
- */
-void setup(void)
+static void verify_setgroups(void)
{
+ groups_set[0] = 42;
- tst_require_root();
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ TST_EXP_PASS(SETGROUPS(1, groups_set));
- TEST_PAUSE;
+ TST_EXP_VAL(GETGROUPS(1, groups_get), 1);
- /* Get the group id info. of TESTUSER from /etc/passwd */
- if ((user_info = getpwnam(TESTUSER)) == NULL) {
- tst_brkm(TFAIL, cleanup, "getpwnam(2) of %s Failed", TESTUSER);
- }
+ TST_EXP_EQ_LI(groups_get[0], groups_set[0]);
- if (!GID_SIZE_CHECK(user_info->pw_gid)) {
- tst_brkm(TBROK,
- cleanup,
- "gid returned from getpwnam is too large for testing setgroups16");
- }
-
- groups_list[0] = user_info->pw_gid;
+ groups_get[0] = 0;
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-
-}
+static struct tst_test test = {
+ .test_all = verify_setgroups,
+ .bufs = (struct tst_buffers []) {
+ {&groups_get, .size = sizeof(GID_T)},
+ {&groups_set, .size = sizeof(GID_T)},
+ {},
+ },
+ .needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/setgroups/setgroups03.c b/testcases/kernel/syscalls/setgroups/setgroups03.c
index 490b06996..fbf8de0bb 100644
--- a/testcases/kernel/syscalls/setgroups/setgroups03.c
+++ b/testcases/kernel/syscalls/setgroups/setgroups03.c
@@ -1,222 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (C) Bull S.A. 2001
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) Linux Test Project, 2003-2023
+ * 07/2001 Ported by Wayne Boyer
+ * 05/2002 Ported by Andre Merlier
*/
-/*
- * Test Name: setgroups03
- *
- * Test Description:
- * Verify that,
- * 1. setgroups() fails with -1 and sets errno to EINVAL if the size
- * argument value is > NGROUPS
- * 2. setgroups() fails with -1 and sets errno to EPERM if the
- * calling process is not super-user.
+/*\
+ * [Description]
*
- * Expected Result:
- * setgroups() should fail with return value -1 and set expected errno.
+ * Test for EINVAL, EPERM, EFAULT errors.
*
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
+ * - setgroups() fails with EINVAL if the size argument value is > NGROUPS.
*
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * if errno set == expected errno
- * Issue sys call fails with expected return value and errno.
- * Otherwise,
- * Issue sys call fails with unexpected errno.
- * Otherwise,
- * Issue sys call returns unexpected value.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- * Usage: <for command-line>
- * setgroups03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- * This test should be executed by 'non-super-user' only.
+ * - setgroups() fails with EPERM if the calling process is not super-user.
*
+ * - setgroups() fails with EFAULT if the list has an invalid address.
*/
-#include <limits.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
-#include "test.h"
+#include <pwd.h>
+#include <stdlib.h>
-#include "compat_16.h"
+#include "tst_test.h"
+#include "compat_tst_16.h"
#define TESTUSER "nobody"
-char nobody_uid[] = "nobody";
-struct passwd *ltpuser;
+static GID_T *glist1, *glist2, *glist3;
+static struct passwd *user_info;
-TCID_DEFINE(setgroups03);
-int TST_TOTAL = 2;
-
-GID_T *groups_list; /* Array to hold gids for getgroups() */
-
-int setup1(); /* setup function to test error EPERM */
-void setup(); /* setup function for the test */
-void cleanup(); /* cleanup function for the test */
-
-struct test_case_t { /* test case struct. to hold ref. test cond's */
- size_t gsize_add;
- int list;
- char *desc;
+static struct tcase {
+ int gsize;
+ GID_T **glist;
int exp_errno;
- int (*setupfunc) ();
-} Test_cases[] = {
- {
- 1, 1, "Size is > sysconf(_SC_NGROUPS_MAX)", EINVAL, NULL}, {
- 0, 2, "Permission denied, not super-user", EPERM, setup1}
+} tcases[] = {
+ {NGROUPS + 1, &glist1, EINVAL},
+ {1, &glist2, EPERM},
+ {NGROUPS, &glist3, EFAULT},
};
-int main(int ac, char **av)
-{
- int lc;
- int gidsetsize; /* total no. of groups */
- int i;
- char *test_desc; /* test specific error message */
- int ngroups_max = sysconf(_SC_NGROUPS_MAX); /* max no. of groups in the current system */
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- groups_list = malloc(ngroups_max * sizeof(GID_T));
- if (groups_list == NULL) {
- tst_brkm(TBROK, NULL, "malloc failed to alloc %zu errno "
- " %d ", ngroups_max * sizeof(GID_T), errno);
- }
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++) {
- if (Test_cases[i].setupfunc != NULL) {
- Test_cases[i].setupfunc();
- }
-
- gidsetsize = ngroups_max + Test_cases[i].gsize_add;
- test_desc = Test_cases[i].desc;
-
- /*
- * Call setgroups() to test different test conditions
- * verify that it fails with -1 return value and
- * sets appropriate errno.
- */
- TEST(SETGROUPS(cleanup, gidsetsize, groups_list));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "setgroups(%d) returned %ld, "
- "expected -1, errno=%d", gidsetsize,
- TEST_RETURN, Test_cases[i].exp_errno);
- continue;
- }
-
- if (TEST_ERRNO == Test_cases[i].exp_errno) {
- tst_resm(TPASS,
- "setgroups(%d) fails, %s, errno=%d",
- gidsetsize, test_desc, TEST_ERRNO);
- } else {
- tst_resm(TFAIL, "setgroups(%d) fails, %s, "
- "errno=%d, expected errno=%d",
- gidsetsize, test_desc, TEST_ERRNO,
- Test_cases[i].exp_errno);
- }
- }
-
- }
-
- cleanup();
-
- tst_exit();
-}
-
-/*
- * setup() - performs all ONE TIME setup for this test.
- *
- * Call individual test specific setup functions.
- */
-void setup(void)
+static void verify_setgroups(unsigned int i)
{
- tst_require_root();
+ struct tcase *tc = &tcases[i];
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ if (tc->exp_errno == EPERM)
+ SAFE_SETEUID(user_info->pw_uid);
- TEST_PAUSE;
+ TST_EXP_FAIL(SETGROUPS(tc->gsize, *tc->glist), tc->exp_errno,
+ "setgroups(%d, groups_list)", tc->gsize);
+ if (tc->exp_errno == EPERM)
+ SAFE_SETEUID(0);
}
-/*
- * setup1 - Setup function to test setgroups() which returns -1
- * and sets errno to EPERM.
- *
- * Get the user info. from /etc/passwd file.
- * This function returns 0 on success.
- */
-int setup1(void)
+static void setup(void)
{
- struct passwd *user_info; /* struct. to hold test user info */
-
-/* Switch to nobody user for correct error code collection */
- ltpuser = getpwnam(nobody_uid);
- if (seteuid(ltpuser->pw_uid) == -1) {
- tst_resm(TINFO, "setreuid failed to "
- "to set the effective uid to %d", ltpuser->pw_uid);
- perror("setreuid");
- }
-
- if ((user_info = getpwnam(TESTUSER)) == NULL) {
- tst_brkm(TFAIL, cleanup, "getpwnam(2) of %s Failed", TESTUSER);
- }
-
- if (!GID_SIZE_CHECK(user_info->pw_gid)) {
- tst_brkm(TBROK,
- cleanup,
- "gid returned from getpwnam is too large for testing setgroups16");
- }
- groups_list[0] = user_info->pw_gid;
- return 0;
+ user_info = SAFE_GETPWNAM(TESTUSER);
+ glist2[0] = 42;
+ glist3 = tst_get_bad_addr(NULL);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-
-}
+static struct tst_test test = {
+ .test = verify_setgroups,
+ .tcnt = ARRAY_SIZE(tcases),
+ .bufs = (struct tst_buffers []) {
+ {&glist1, .size = sizeof(GID_T) * (NGROUPS + 1)},
+ {&glist2, .size = sizeof(GID_T)},
+ {&user_info, .size = sizeof(struct passwd)},
+ {},
+ },
+ .setup = setup,
+ .needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/setgroups/setgroups04.c b/testcases/kernel/syscalls/setgroups/setgroups04.c
deleted file mode 100644
index 971c86bd2..000000000
--- a/testcases/kernel/syscalls/setgroups/setgroups04.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) Bull S.A. 2001
- * Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Test Name: setgroups04
- *
- * Test Description:
- * Verify that, setgroups() fails with -1 and sets errno to EFAULT if the list has an invalid address.
- *
- * Expected Result:
- * setgroups() should fail with return value -1 and set expected errno.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * if errno set == expected errno
- * Issue sys call fails with expected return value and errno.
- * Otherwise,
- * Issue sys call fails with unexpected errno.
- * Otherwise,
- * Issue sys call returns unexpected value.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- * Usage: <for command-line>
- * setgroups04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 05/2002 Ported by André Merlier
- *
- * RESTRICTIONS:
- * none.
- *
- */
-#include <sys/types.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include "test.h"
-
-#include "compat_16.h"
-
-TCID_DEFINE(setgroups04);
-int TST_TOTAL = 1;
-
-GID_T groups_list[NGROUPS];
-
-void setup(); /* setup function for the test */
-void cleanup(); /* cleanup function for the test */
-
-#if !defined(UCLINUX)
-
-int main(int ac, char **av)
-{
- int lc;
- int gidsetsize; /* total no. of groups */
- char *test_desc; /* test specific error message */
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- /* Perform setup for test */
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- gidsetsize = NGROUPS;
- test_desc = "EFAULT";
-
- /*
- * Call setgroups() to test condition
- * verify that it fails with -1 return value and
- * sets appropriate errno.
- */
- TEST(SETGROUPS(cleanup, gidsetsize, sbrk(0)));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "setgroups() returned %ld, "
- "expected -1, errno=%d", TEST_RETURN,
- EFAULT);
- } else {
-
- if (TEST_ERRNO == EFAULT) {
- tst_resm(TPASS,
- "setgroups() fails with expected "
- "error EFAULT errno:%d", TEST_ERRNO);
- } else {
- tst_resm(TFAIL, "setgroups() fails, %s, "
- "errno=%d, expected errno=%d",
- test_desc, TEST_ERRNO, EFAULT);
- }
- }
-
- }
-
- cleanup();
- tst_exit();
-
-}
-
-#else
-
-int main(void)
-{
- tst_resm(TINFO, "test is not available on uClinux");
- tst_exit();
-}
-
-#endif /* if !defined(UCLINUX) */
-
-/*
- * setup()
- */
-void setup(void)
-{
- tst_require_root();
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
-}
-
-/*
- * cleanup()
- */
-void cleanup(void)
-{
-
-}
diff --git a/testcases/kernel/syscalls/setpgid/setpgid02.c b/testcases/kernel/syscalls/setpgid/setpgid02.c
index 4b63afee8..b380d7df4 100644
--- a/testcases/kernel/syscalls/setpgid/setpgid02.c
+++ b/testcases/kernel/syscalls/setpgid/setpgid02.c
@@ -13,15 +13,15 @@
* - EINVAL when given pgid is less than 0.
* - ESRCH when pid is not the calling process and not a child of
* the calling process.
- * - EPERM when an attempt was made to move a process into a process
- * group in a different session.
+ * - EPERM when an attempt was made to move a process into a nonexisting
+ * process group.
*/
#include <errno.h>
#include <unistd.h>
#include "tst_test.h"
-static pid_t pgid, pid, ppid, init_pgid;
+static pid_t pgid, pid, ppid, inval_pgid;
static pid_t negative_pid = -1;
static struct tcase {
@@ -31,7 +31,7 @@ static struct tcase {
} tcases[] = {
{&pid, &negative_pid, EINVAL},
{&ppid, &pgid, ESRCH},
- {&pid, &init_pgid, EPERM}
+ {&pid, &inval_pgid, EPERM}
};
static void setup(void)
@@ -41,10 +41,10 @@ static void setup(void)
pgid = getpgrp();
/*
- * Getting pgid of init/systemd process to use it as a
- * process group from a different session for EPERM test
+ * pid_max would not be in use by another process and guarantees that
+ * it corresponds to an invalid PGID, generating EPERM.
*/
- init_pgid = SAFE_GETPGID(1);
+ SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%d\n", &inval_pgid);
}
static void run(unsigned int n)
diff --git a/testcases/kernel/syscalls/setpgid/setpgid03.c b/testcases/kernel/syscalls/setpgid/setpgid03.c
index 79ca23e08..9ce2603d8 100644
--- a/testcases/kernel/syscalls/setpgid/setpgid03.c
+++ b/testcases/kernel/syscalls/setpgid/setpgid03.c
@@ -9,7 +9,9 @@
/*\
* [Description]
*
- * Tests setpgid() erorrs:
+ * Tests setpgid(2) errors:
+ *
+ * - EPERM The process specified by pid must not be a session leader.
*
* - EPERM The calling process, process specified by pid and the target
* process group must be in the same session.
@@ -43,6 +45,8 @@ static void run(void)
TST_CHECKPOINT_WAIT(0);
TST_EXP_FAIL(setpgid(child_pid, getppid()), EPERM);
+ /* Child did setsid(), so its PGID is set to its PID. */
+ TST_EXP_FAIL(setpgid(0, child_pid), EPERM);
TST_CHECKPOINT_WAKE(0);
diff --git a/testcases/kernel/syscalls/setreuid/setreuid04.c b/testcases/kernel/syscalls/setreuid/setreuid04.c
index 8eed90df0..06ffa32b0 100644
--- a/testcases/kernel/syscalls/setreuid/setreuid04.c
+++ b/testcases/kernel/syscalls/setreuid/setreuid04.c
@@ -1,141 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
* Ported by John George
+ * Copyright (c) 2022 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test that root can change the real and effective uid to an
- * unpriviledged user.
+/*\
+ * [Description]
+ *
+ * Verify that root user can change the real and effective uid to an
+ * unprivileged user.
*/
-#include <errno.h>
-#include <stdlib.h>
#include <pwd.h>
-#include <sys/wait.h>
-
-#include "test.h"
-#include "compat_16.h"
-
-TCID_DEFINE(setreuid04);
-
-static uid_t neg_one = -1;
-
-static struct passwd nobody, root;
-
-/*
- * The following structure contains all test data. Each structure in the array
- * is used for a separate test. The tests are executed in the for loop below.
- */
-
-struct test_data_t {
- uid_t *real_uid;
- uid_t *eff_uid;
- struct passwd *exp_real_usr;
- struct passwd *exp_eff_usr;
- char *test_msg;
-} test_data[] = {
- {
- &neg_one, &neg_one, &root, &root, "After setreuid(-1, nobody),"}, {
-&nobody.pw_uid, &nobody.pw_uid, &nobody, &nobody,
- "After setreuid(-1, -1),"},};
-
-int TST_TOTAL = ARRAY_SIZE(test_data);
-
-static void setup(void);
-static void cleanup(void);
-static void uid_verify(struct passwd *, struct passwd *, char *);
-
-int main(int ac, char **av)
-{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- int i, pid;
-
- tst_count = 0;
+#include "tst_test.h"
+#include "compat_tst_16.h"
- if ((pid = FORK_OR_VFORK()) == -1) {
- tst_brkm(TBROK, cleanup, "fork failed");
- } else if (pid == 0) { /* child */
-
- for (i = 0; i < TST_TOTAL; i++) {
-
- /* Set the real or effective user id */
- TEST(SETREUID(cleanup, *test_data[i].real_uid,
- *test_data[i].eff_uid));
-
- if (TEST_RETURN != -1) {
- tst_resm(TPASS, "setreuid(%d, %d) "
- "succeeded as expected.",
- *test_data[i].real_uid,
- *test_data[i].eff_uid);
- } else {
- tst_resm(TFAIL, "setreuid(%d, %d) "
- "did not return as expected.",
- *test_data[i].real_uid,
- *test_data[i].eff_uid);
- }
-
- uid_verify(test_data[i].exp_real_usr,
- test_data[i].exp_eff_usr,
- test_data[i].test_msg);
- }
- tst_exit();
- } else { /* parent */
- tst_record_childstatus(cleanup, pid);
- }
- }
- cleanup();
- tst_exit();
-}
+static uid_t root_uid, nobody_uid;
static void setup(void)
{
- tst_require_root();
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- if (getpwnam("nobody") == NULL)
- tst_brkm(TBROK, NULL, "nobody must be a valid user.");
+ struct passwd *nobody;
- root = *(getpwnam("root"));
- UID16_CHECK(root.pw_uid, setreuid, cleanup);
+ root_uid = getuid();
+ nobody = SAFE_GETPWNAM("nobody");
+ nobody_uid = nobody->pw_uid;
- nobody = *(getpwnam("nobody"));
- UID16_CHECK(nobody.pw_uid, setreuid, cleanup);
-
- TEST_PAUSE;
+ UID16_CHECK(nobody_uid, setreuid);
+ UID16_CHECK(root_uid, setreuid);
}
-static void cleanup(void)
+static void run(void)
{
-}
+ if (!SAFE_FORK()) {
+ TST_EXP_PASS(SETREUID(nobody_uid, nobody_uid));
-static void uid_verify(struct passwd *ru, struct passwd *eu, char *when)
-{
- if ((getuid() != ru->pw_uid) || (geteuid() != eu->pw_uid)) {
- tst_resm(TFAIL, "ERROR: %s real uid = %d; effective uid = %d",
- when, getuid(), geteuid());
- tst_resm(TINFO, "Expected: real uid = %d; effective uid = %d",
- ru->pw_uid, eu->pw_uid);
+ TST_EXP_EQ_LI(GETUID(), nobody_uid);
+ TST_EXP_EQ_LI(GETEUID(), nobody_uid);
}
+ tst_reap_children();
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1
+};
diff --git a/testcases/kernel/syscalls/setreuid/setreuid07.c b/testcases/kernel/syscalls/setreuid/setreuid07.c
index ff222cd00..5faf3cb7f 100644
--- a/testcases/kernel/syscalls/setreuid/setreuid07.c
+++ b/testcases/kernel/syscalls/setreuid/setreuid07.c
@@ -1,192 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-later
/*
* Copyright (c) Kerlabs 2008.
* Copyright (c) International Business Machines Corp., 2008
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
* Created by Renaud Lottiaux
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
+/*\
+ * [Description]
+ *
* Check if setreuid behaves correctly with file permissions.
* The test creates a file as ROOT with permissions 0644, does a setreuid
* and then tries to open the file with RDWR permissions.
* The same test is done in a fork to check if new UIDs are correctly
- * passed to the son.
+ * passed to the child process.
*/
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <unistd.h>
#include <pwd.h>
+#include <stdlib.h>
-#include "test.h"
-#include "safe_macros.h"
-#include "compat_16.h"
+#include "tst_test.h"
+#include "compat_tst_16.h"
-TCID_DEFINE(setreuid07);
-int TST_TOTAL = 1;
+#define TEMPFILE "testfile"
-static char testfile[256] = "";
static struct passwd *ltpuser;
-static int fd = -1;
-
-static void setup(void);
-static void cleanup(void);
-static void do_master_child(void);
-
-int main(int ac, char **av)
+static void setup(void)
{
- pid_t pid;
+ int fd;
- tst_parse_opts(ac, av, NULL, NULL);
+ ltpuser = SAFE_GETPWNAM("nobody");
- setup();
-
- pid = FORK_OR_VFORK();
- if (pid < 0)
- tst_brkm(TBROK, cleanup, "Fork failed");
-
- if (pid == 0)
- do_master_child();
-
- tst_record_childstatus(cleanup, pid);
-
- cleanup();
- tst_exit();
+ UID16_CHECK(ltpuser->pw_uid, setreuid);
+ fd = SAFE_OPEN(TEMPFILE, O_CREAT | O_RDWR, 0644);
+ SAFE_CLOSE(fd);
}
-static void do_master_child(void)
+static void run(void)
{
- int lc;
- int pid;
- int status;
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- int tst_fd;
-
- tst_count = 0;
-
- if (SETREUID(NULL, 0, ltpuser->pw_uid) == -1) {
- perror("setreuid failed");
- exit(TFAIL);
- }
-
- /* Test 1: Check the process with new uid cannot open the file
- * with RDWR permissions.
- */
- TEST(tst_fd = open(testfile, O_RDWR));
-
- if (TEST_RETURN != -1) {
- printf("open succeeded unexpectedly\n");
- close(tst_fd);
- exit(TFAIL);
- }
-
- if (TEST_ERRNO == EACCES) {
- printf("open failed with EACCES as expected\n");
- } else {
- perror("open failed unexpectedly");
- exit(TFAIL);
- }
-
- /* Test 2: Check a son process cannot open the file
- * with RDWR permissions.
- */
- pid = FORK_OR_VFORK();
- if (pid < 0)
- tst_brkm(TBROK, cleanup, "Fork failed");
-
- if (pid == 0) {
- int tst_fd2;
-
- /* Test to open the file in son process */
- TEST(tst_fd2 = open(testfile, O_RDWR));
-
- if (TEST_RETURN != -1) {
- printf("call succeeded unexpectedly\n");
- close(tst_fd2);
- exit(TFAIL);
- }
-
- if (TEST_ERRNO == EACCES) {
- printf("open failed with EACCES as expected\n");
- exit(TPASS);
- } else {
- printf("open failed unexpectedly\n");
- exit(TFAIL);
- }
- } else {
- /* Wait for son completion */
- if (waitpid(pid, &status, 0) == -1) {
- perror("waitpid failed");
- exit(TFAIL);
- }
- if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
- exit(WEXITSTATUS(status));
- }
-
- /* Test 3: Fallback to initial uid and check we can again open
- * the file with RDWR permissions.
- */
- tst_count++;
- if (SETREUID(NULL, 0, 0) == -1) {
- perror("setreuid failed");
- exit(TFAIL);
- }
+ pid_t pid;
- TEST(tst_fd = open(testfile, O_RDWR));
+ TST_EXP_PASS_SILENT(SETREUID(-1, ltpuser->pw_uid));
+ TST_EXP_FAIL2(open(TEMPFILE, O_RDWR), EACCES);
- if (TEST_RETURN == -1) {
- perror("open failed unexpectedly");
- exit(TFAIL);
- } else {
- printf("open call succeeded\n");
- close(tst_fd);
- }
+ pid = SAFE_FORK();
+ if (pid == 0) {
+ TST_EXP_FAIL2(open(TEMPFILE, O_RDWR), EACCES);
+ exit(0);
}
- exit(TPASS);
-}
+ tst_reap_children();
-static void setup(void)
-{
- tst_require_root();
-
- ltpuser = getpwnam("nobody");
- if (ltpuser == NULL)
- tst_brkm(TBROK, NULL, "nobody must be a valid user.");
-
- tst_tmpdir();
-
- sprintf(testfile, "setreuid07file%d.tst", getpid());
-
- /* Create test file */
- fd = SAFE_OPEN(cleanup, testfile, O_CREAT | O_RDWR, 0644);
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ TST_EXP_PASS_SILENT(SETREUID(-1, 0));
+ TST_EXP_FD(open(TEMPFILE, O_RDWR));
+ SAFE_CLOSE(TST_RET);
}
-static void cleanup(void)
-{
- close(fd);
-
- tst_rmdir();
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1
+};
diff --git a/testcases/kernel/syscalls/setsockopt/setsockopt02.c b/testcases/kernel/syscalls/setsockopt/setsockopt02.c
index e7621538b..3349c9970 100644
--- a/testcases/kernel/syscalls/setsockopt/setsockopt02.c
+++ b/testcases/kernel/syscalls/setsockopt/setsockopt02.c
@@ -96,4 +96,8 @@ static struct tst_test test = {
.needs_root = 1,
.setup = setup,
.cleanup = cleanup,
+ .tags = (const struct tst_tag[]) {
+ {"CVE", "2017-7308"},
+ {}
+ }
};
diff --git a/testcases/kernel/syscalls/setsockopt/setsockopt08.c b/testcases/kernel/syscalls/setsockopt/setsockopt08.c
index 5fc1a8b8e..7f8243de1 100644
--- a/testcases/kernel/syscalls/setsockopt/setsockopt08.c
+++ b/testcases/kernel/syscalls/setsockopt/setsockopt08.c
@@ -26,57 +26,63 @@
* ->targetsize: if OTOH the user specified ->u.user.target_size is
* too small, then the memset() destination address calculated by
* adding ->targetsize to the payload start will not point at, but
- * into or even past the padding. For the table's last entry's target
- * record, this will result in an out-of-bounds write past the
- * destination buffer allocated for the converted table. The code
- * below will create a (compat) table such that the converted table's
- * calculated size will fit exactly into a slab size of 1024 bytes and
- * that the memset() in xt_compat_target_from_user() will write past
- * this slab.
+ * into or even past the padding.
+ *
+ * For the table's last entry's target record, this will result in an
+ * out-of-bounds write past the destination buffer allocated for the converted
+ * table. The code below will create a (compat) table such that the converted
+ * table's calculated size will fit exactly into a slab size of 1024 bytes and
+ * that the memset() in xt_compat_target_from_user() will write past this slab.
*
* The table will consist of
- * - the mandatory struct compat_ipt_replace header,
- * - a single entry consisting of
- * - the mandatory compat_ipt_entry header
- * - a single 'state' match entry of appropriate size for
+ *
+ * * the mandatory struct compat_ipt_replace header,
+ * * a single entry consisting of
+ * ** the mandatory compat_ipt_entry header
+ * ** a single 'state' match entry of appropriate size for
* controlling the out-of-bounds write when converting
* the target entry following next,
- * - a single 'REJECT' target entry.
+ * ** a single 'REJECT' target entry.
+ *
* The kernel will transform this into a buffer containing (in
* this order)
- * - a xt_table_info
- * - a single entry consisting of
- * - its ipt_entry header
- * - a single 'state' match entry
- * - followed by a single 'REJECT' target entry.
+ *
+ * * a xt_table_info
+ * * a single entry consisting of
+ * ** its ipt_entry header
+ * ** a single 'state' match entry
+ * ** followed by a single 'REJECT' target entry.
*
* The expected sizes for the 'state' match entries as well as the
* 'REJECT' target are the size of the base header struct (32 bytes)
- * plus the size of an unsigned int (4 bytes) each. In the course of
- * the compat => non-compat conversion, the kernel will insert four
- * bytes of padding after the unsigned int payload (c.f. 'off'
- * adjustments via xt_compat_match_offset() and
- * xt_compat_target_offset() in xt_compat_match_from_user() and
- * xt_compat_target_from_user() resp.). This code is based on the
- * premise that the user sets the given ->u.user.match_size or
- * ->u.user.target_size consistent to the COMPAT_XT_ALIGN()ed payload
- * size as specified by the corresponding xt_match instance's
- * ->matchsize or xt_target instance's ->targetsize. That is, the
- * padding gets inserted unconditionally during the transformation,
+ * plus the size of an unsigned int (4 bytes) each.
+ *
+ * In the course of the compat => non-compat conversion, the kernel will insert
+ * four bytes of padding after the unsigned int payload (c.f. 'off' adjustments
+ * via xt_compat_match_offset() and xt_compat_target_offset() in
+ * xt_compat_match_from_user() and xt_compat_target_from_user() resp.).
+ *
+ * This code is based on the premise that the user sets the given
+ * ->u.user.match_size or ->u.user.target_size consistent to the
+ * COMPAT_XT_ALIGN()ed payload size as specified by the corresponding xt_match
+ * instance's ->matchsize or xt_target instance's ->targetsize.
+ *
+ * That is, the padding gets inserted unconditionally during the transformation,
* independent of the actual values of ->u.user.match_size or
- * ->u.user.target_size and the result ends up getting layed out with
- * proper alignment only if said values match the expectations. That's
- * not a problem in itself, but this unconditional insertion of
- * padding must be taken into account in the match_size calculation
- * below.
+ * ->u.user.target_size and the result ends up getting layed out with proper
+ * alignment only if said values match the expectations.
+ *
+ * That's not a problem in itself, but this unconditional insertion of padding
+ * must be taken into account in the match_size calculation below.
*
* For the match_size calculation below, note that the chosen
* target slab size is 1024 and that
- * - sizeof(xt_table_info) = 64
- * - sizeof(ipt_entry) = 112
- * - the kernel will insert four bytes of padding
+ *
+ * * sizeof(xt_table_info) = 64
+ * * sizeof(ipt_entry) = 112
+ * * the kernel will insert four bytes of padding
* after the match and target entries each.
- * - sizeof(struct xt_entry_target) = 32
+ * * sizeof(struct xt_entry_target) = 32
*/
#include <netinet/in.h>
diff --git a/testcases/kernel/syscalls/sockioctl/sockioctl01.c b/testcases/kernel/syscalls/sockioctl/sockioctl01.c
index 51dac9c16..ff3738f32 100644
--- a/testcases/kernel/syscalls/sockioctl/sockioctl01.c
+++ b/testcases/kernel/syscalls/sockioctl/sockioctl01.c
@@ -52,7 +52,7 @@ static struct ifreq ifr;
static int sinlen;
static int optval;
-static char buf[8192];
+static struct ifreq buf[200];
static void setup(void);
static void setup0(void);
@@ -218,7 +218,7 @@ static void setup2(void)
s = SAFE_SOCKET(cleanup, tdat[testno].domain, tdat[testno].type,
tdat[testno].proto);
ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
+ ifc.ifc_buf = (char *)buf;
}
static void setup3(void)
diff --git a/testcases/kernel/syscalls/stat/stat01.c b/testcases/kernel/syscalls/stat/stat01.c
index e0dbfbf2f..365cdac8a 100644
--- a/testcases/kernel/syscalls/stat/stat01.c
+++ b/testcases/kernel/syscalls/stat/stat01.c
@@ -8,9 +8,9 @@
/*\
* [Description]
*
- * Verify that, stat(2) succeeds to get the status of a file and fills the
- * stat structure elements regardless of whether process has or doesn't
- * have read access to the file.
+ * Verify that, stat(2) succeeds to get the status of a file and fills the
+ * stat structure elements regardless of whether process has or doesn't
+ * have read access to the file.
*/
#include <pwd.h>
diff --git a/testcases/kernel/syscalls/statvfs/statvfs02.c b/testcases/kernel/syscalls/statvfs/statvfs02.c
index 8aaa47318..6f36530bf 100644
--- a/testcases/kernel/syscalls/statvfs/statvfs02.c
+++ b/testcases/kernel/syscalls/statvfs/statvfs02.c
@@ -10,6 +10,7 @@
* [Description]
*
* Verify that statvfs() fails with:
+ *
* - EFAULT when path points to an invalid address.
* - ELOOP when too many symbolic links were encountered in translating path.
* - ENAMETOOLONG when path is too long.
diff --git a/testcases/kernel/syscalls/statx/.gitignore b/testcases/kernel/syscalls/statx/.gitignore
index 1cea43c0d..f6a423eed 100644
--- a/testcases/kernel/syscalls/statx/.gitignore
+++ b/testcases/kernel/syscalls/statx/.gitignore
@@ -7,3 +7,6 @@
/statx07
/statx08
/statx09
+/statx10
+/statx11
+/statx12
diff --git a/testcases/kernel/syscalls/statx/statx01.c b/testcases/kernel/syscalls/statx/statx01.c
index 68f56549f..f9c2748d2 100644
--- a/testcases/kernel/syscalls/statx/statx01.c
+++ b/testcases/kernel/syscalls/statx/statx01.c
@@ -33,6 +33,7 @@
#include "tst_test.h"
#include "tst_safe_macros.h"
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#include "tst_safe_stdio.h"
#include <string.h>
#include <inttypes.h>
diff --git a/testcases/kernel/syscalls/statx/statx02.c b/testcases/kernel/syscalls/statx/statx02.c
index a8e868d7a..5ed80894d 100644
--- a/testcases/kernel/syscalls/statx/statx02.c
+++ b/testcases/kernel/syscalls/statx/statx02.c
@@ -28,6 +28,7 @@
#include "tst_test.h"
#include "tst_safe_macros.h"
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#define TESTFILE "test_temp"
#define LINK_FILE "test_temp_ln"
diff --git a/testcases/kernel/syscalls/statx/statx03.c b/testcases/kernel/syscalls/statx/statx03.c
index b88809063..2465d8773 100644
--- a/testcases/kernel/syscalls/statx/statx03.c
+++ b/testcases/kernel/syscalls/statx/statx03.c
@@ -24,6 +24,7 @@
#include "tst_safe_macros.h"
#include "tst_get_bad_addr.h"
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#define TESTFILE "test_file"
#define MODE 0644
diff --git a/testcases/kernel/syscalls/statx/statx04.c b/testcases/kernel/syscalls/statx/statx04.c
index 3923b7f8e..58296bd24 100644
--- a/testcases/kernel/syscalls/statx/statx04.c
+++ b/testcases/kernel/syscalls/statx/statx04.c
@@ -52,10 +52,11 @@
*/
#define _GNU_SOURCE
+#include <stdlib.h>
#include "tst_test.h"
#include "lapi/fs.h"
-#include <stdlib.h>
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#define MOUNT_POINT "mntpoint"
#define TESTDIR MOUNT_POINT "/testdir"
diff --git a/testcases/kernel/syscalls/statx/statx05.c b/testcases/kernel/syscalls/statx/statx05.c
index f62dadd5c..9781b3e70 100644
--- a/testcases/kernel/syscalls/statx/statx05.c
+++ b/testcases/kernel/syscalls/statx/statx05.c
@@ -27,6 +27,7 @@
#include "tst_test.h"
#include "lapi/fs.h"
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#define MNTPOINT "mnt_point"
#define TESTDIR_FLAGGED MNTPOINT"/test_dir1"
diff --git a/testcases/kernel/syscalls/statx/statx06.c b/testcases/kernel/syscalls/statx/statx06.c
index fa75982b0..1771dff49 100644
--- a/testcases/kernel/syscalls/statx/statx06.c
+++ b/testcases/kernel/syscalls/statx/statx06.c
@@ -111,10 +111,10 @@ static void test_statx(unsigned int test_nr)
clock_wait_tick();
SAFE_CLOCK_GETTIME(CLOCK_REALTIME, &after_time);
- TEST(statx(AT_FDCWD, TEST_FILE, 0, STATX_ALL, &buff));
+ TEST(statx(AT_FDCWD, TEST_FILE, 0, STATX_BASIC_STATS | STATX_BTIME, &buff));
if (TST_RET != 0) {
tst_brk(TFAIL | TTERRNO,
- "statx(AT_FDCWD, %s, 0, STATX_ALL, &buff)",
+ "statx(AT_FDCWD, %s, 0, STATX_BASIC_STATS | STATX_BTIME, &buff)",
TEST_FILE);
}
diff --git a/testcases/kernel/syscalls/statx/statx07.c b/testcases/kernel/syscalls/statx/statx07.c
index 8cb3e9b6d..4dbf83e18 100644
--- a/testcases/kernel/syscalls/statx/statx07.c
+++ b/testcases/kernel/syscalls/statx/statx07.c
@@ -27,12 +27,7 @@
* but mode has been chaged in server file.
*
* The support for SYNC flags was implemented in NFS in:
- *
- * commit 9ccee940bd5b766b6dab6c1a80908b9490a4850d
- * Author: Trond Myklebust <trond.myklebust@primarydata.com>
- * Date: Thu Jan 4 17:46:09 2018 -0500
- *
- * Support statx() mask and query flags parameters
+ * 9ccee940bd5b ("Support statx() mask and query flags parameters")
*/
#define _GNU_SOURCE
@@ -44,6 +39,7 @@
#include <sys/mount.h>
#include "tst_test.h"
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#define MODE(X) (X & (~S_IFMT))
#define FLAG_NAME(x) .flag = x, .flag_name = #x
@@ -67,15 +63,15 @@ static int get_mode(char *file_name, int flag_type, char *flag_name)
{
struct statx buf;
- TEST(statx(AT_FDCWD, file_name, flag_type, STATX_ALL, &buf));
+ TEST(statx(AT_FDCWD, file_name, flag_type, STATX_BASIC_STATS, &buf));
if (TST_RET == -1) {
tst_brk(TFAIL | TST_ERR,
- "statx(AT_FDCWD, %s, %s, STATX_ALL, &buf)",
+ "statx(AT_FDCWD, %s, %s, STATX_BASIC_STATS, &buf)",
file_name, flag_name);
}
- tst_res(TINFO, "statx(AT_FDCWD, %s, %s, STATX_ALL, &buf) = %o",
+ tst_res(TINFO, "statx(AT_FDCWD, %s, %s, STATX_BASIC_STATS, &buf) = %o",
file_name, flag_name, buf.stx_mode);
return buf.stx_mode;
diff --git a/testcases/kernel/syscalls/statx/statx08.c b/testcases/kernel/syscalls/statx/statx08.c
index 10b1ca460..64b36986d 100644
--- a/testcases/kernel/syscalls/statx/statx08.c
+++ b/testcases/kernel/syscalls/statx/statx08.c
@@ -26,6 +26,7 @@
#include "lapi/fs.h"
#include <stdlib.h>
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#define MOUNT_POINT "mntpoint"
#define TESTDIR_FLAGGED MOUNT_POINT"/test_dir1"
diff --git a/testcases/kernel/syscalls/statx/statx09.c b/testcases/kernel/syscalls/statx/statx09.c
index aea329e08..6e75ff3ec 100644
--- a/testcases/kernel/syscalls/statx/statx09.c
+++ b/testcases/kernel/syscalls/statx/statx09.c
@@ -20,10 +20,12 @@
#define _GNU_SOURCE
#include <sys/mount.h>
#include <stdlib.h>
+#include <stdio.h>
#include "tst_test.h"
#include "lapi/fs.h"
#include "lapi/fsverity.h"
#include "lapi/stat.h"
+#include "lapi/fcntl.h"
#include <inttypes.h>
#define MNTPOINT "mnt_point"
@@ -79,8 +81,10 @@ static void flag_setup(void)
{
int fd, attr, ret;
struct fsverity_enable_arg enable;
+ struct stat statbuf;
fd = SAFE_OPEN(TESTFILE_FLAGGED, O_RDONLY, 0664);
+ SAFE_FSTAT(fd, &statbuf);
ret = ioctl(fd, FS_IOC_GETFLAGS, &attr);
if (ret < 0) {
@@ -93,7 +97,7 @@ static void flag_setup(void)
memset(&enable, 0, sizeof(enable));
enable.version = 1;
enable.hash_algorithm = hash_algorithms[0];
- enable.block_size = 4096;
+ enable.block_size = statbuf.st_blksize;
enable.salt_size = 0;
enable.salt_ptr = (intptr_t)NULL;
enable.sig_size = 0;
@@ -117,6 +121,12 @@ static void flag_setup(void)
static void setup(void)
{
+ char opt_bsize[32];
+ const char *const fs_opts[] = {"-O verity", opt_bsize, NULL};
+
+ snprintf(opt_bsize, sizeof(opt_bsize), "-b %i", getpagesize());
+ SAFE_MKFS(tst_device->dev, tst_device->fs_type, fs_opts, NULL);
+
TEST(mount(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, NULL));
if (TST_RET) {
if (TST_ERR == EINVAL)
@@ -144,10 +154,9 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.needs_root = 1,
+ .needs_device = 1,
.mntpoint = MNTPOINT,
- .format_device = 1,
.dev_fs_type = "ext4",
- .dev_fs_opts = (const char *const []){"-O verity", NULL},
.needs_kconfigs = (const char *[]) {
"CONFIG_FS_VERITY",
NULL
diff --git a/testcases/kernel/syscalls/statx/statx10.c b/testcases/kernel/syscalls/statx/statx10.c
new file mode 100644
index 000000000..42106285e
--- /dev/null
+++ b/testcases/kernel/syscalls/statx/statx10.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test for STATX_DIOALIGN mask on ext4 and xfs filesystem.
+ *
+ * - STATX_DIOALIGN Want stx_dio_mem_align and stx_dio_offset_align value
+ *
+ * Check these two values are nonzero under dio situation when STATX_DIOALIGN
+ * in the request mask.
+ *
+ * On ext4, files that use certain filesystem features (data journaling,
+ * encryption, and verity) fall back to buffered I/O. But ltp creates own
+ * filesystem by enabling mount_device in tst_test struct. If we set block
+ * device to LTP_DEV environment, we use this block device to mount by using
+ * default mount option. Otherwise, use loop device to simuate it. So it can
+ * avoid these above situations and don't fall back to buffered I/O.
+ *
+ * Minimum Linux version required is v6.1.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include "tst_test.h"
+#include "lapi/stat.h"
+#include "lapi/fcntl.h"
+
+#define MNTPOINT "mnt_point"
+#define TESTFILE MNTPOINT"/testfile"
+
+static void verify_statx(void)
+{
+ struct statx buf;
+
+ TST_EXP_PASS_SILENT(statx(AT_FDCWD, TESTFILE, 0, STATX_DIOALIGN, &buf),
+ "statx(AT_FDCWD, %s, 0, STATX_DIOALIGN, &buf)", TESTFILE);
+
+ if (!(buf.stx_mask & STATX_DIOALIGN)) {
+ tst_res(TCONF, "Filesystem does not support STATX_DIOALIGN");
+ return;
+ }
+
+#ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN
+ if (buf.stx_dio_mem_align != 0)
+ tst_res(TPASS, "stx_dio_mem_align:%u", buf.stx_dio_mem_align);
+ else
+ tst_res(TFAIL, "stx_dio_mem_align was 0, but DIO should be supported");
+
+ if (buf.stx_dio_offset_align != 0)
+ tst_res(TPASS, "stx_dio_offset_align:%u", buf.stx_dio_offset_align);
+ else
+ tst_res(TFAIL, "stx_dio_offset_align was 0, but DIO should be supported");
+#else
+ tst_res(TCONF, "glibc statx struct miss stx_dio_mem_align field");
+#endif
+}
+
+static void setup(void)
+{
+ int fd = -1;
+
+ if (strcmp(tst_device->fs_type, "xfs") && strcmp(tst_device->fs_type, "ext4"))
+ tst_brk(TCONF, "This test only supports ext4 and xfs");
+
+ SAFE_FILE_PRINTF(TESTFILE, "AAAA");
+ fd = open(TESTFILE, O_RDWR | O_DIRECT);
+ if (fd == -1) {
+ if (errno == EINVAL)
+ tst_brk(TCONF,
+ "The regular file is not on a filesystem that support DIO");
+ else
+ tst_brk(TBROK | TERRNO,
+ "The regular file is open with O_RDWR | O_DIRECT failed");
+ }
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .test_all = verify_statx,
+ .setup = setup,
+ .needs_root = 1,
+ .mntpoint = MNTPOINT,
+ .mount_device = 1,
+ .all_filesystems = 1,
+};
diff --git a/testcases/kernel/syscalls/statx/statx11.c b/testcases/kernel/syscalls/statx/statx11.c
new file mode 100644
index 000000000..653050855
--- /dev/null
+++ b/testcases/kernel/syscalls/statx/statx11.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test for STATX_DIOALIGN mask on block device.
+ *
+ * - STATX_DIOALIGN Want stx_dio_mem_align and stx_dio_offset_align value
+ *
+ * These two values are tightly coupled to the kernel's current DIO
+ * restrictions on block devices.
+ *
+ * Minimum Linux version required is v6.1.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "tst_test.h"
+#include "lapi/stat.h"
+
+static char sys_bdev_dma_path[1024], sys_bdev_logical_path[1024];
+
+static void verify_statx(void)
+{
+ struct statx buf;
+
+ TST_EXP_PASS_SILENT(statx(AT_FDCWD, tst_device->dev, 0, STATX_DIOALIGN, &buf),
+ "statx(AT_FDCWD, %s, 0, STATX_DIOALIGN, &buf)", tst_device->dev);
+
+ if (!(buf.stx_mask & STATX_DIOALIGN)) {
+ tst_res(TCONF, "Filesystem does not support STATX_DIOALIGN");
+ return;
+ }
+
+#ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN
+ /*
+ * This test is tightly coupled to the kernel's current DIO restrictions
+ * on block devices. The general rule of DIO needing to be aligned to the
+ * block device's logical block size was relaxed to allow user buffers
+ * (but not file offsets) aligned to the DMA alignment instead. See v6.0
+ * commit bf8d08532bc1 ("iomap: add support for dma aligned direct-io") and
+ * they are subject to further change in the future.
+ * Also can see commit 2d985f8c6b9 ("vfs: support STATX_DIOALIGN on block devices).
+ */
+ TST_ASSERT_ULONG(sys_bdev_dma_path, buf.stx_dio_mem_align - 1);
+ TST_ASSERT_ULONG(sys_bdev_logical_path, buf.stx_dio_offset_align);
+#else
+ tst_res(TCONF, "glibc statx struct miss stx_dio_mem_align field");
+#endif
+}
+
+static void setup(void)
+{
+ char full_name[256];
+ char *dev_name;
+
+ strcpy(full_name, tst_device->dev);
+ dev_name = SAFE_BASENAME(full_name);
+ sprintf(sys_bdev_logical_path, "/sys/block/%s/queue/logical_block_size", dev_name);
+
+ /*
+ * Since /sys/block/%s/queue doesn't exist for partition, we need to
+ * use a while to search block device instead of partition.
+ */
+ while (access(sys_bdev_logical_path, F_OK) != 0) {
+ dev_name[strlen(dev_name)-1] = '\0';
+ sprintf(sys_bdev_logical_path, "/sys/block/%s/queue/logical_block_size", dev_name);
+ }
+
+ sprintf(sys_bdev_dma_path, "/sys/block/%s/queue/dma_alignment", dev_name);
+ if (access(sys_bdev_dma_path, F_OK) != 0)
+ tst_brk(TCONF, "dma_alignment sysfs file doesn't exist");
+}
+
+static struct tst_test test = {
+ .test_all = verify_statx,
+ .setup = setup,
+ .needs_device = 1,
+ .needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/statx/statx12.c b/testcases/kernel/syscalls/statx/statx12.c
new file mode 100644
index 000000000..432f1cb77
--- /dev/null
+++ b/testcases/kernel/syscalls/statx/statx12.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test for STATX_ATTR_MOUNT_ROOT flag.
+ *
+ * This flag indicates whether the path or fd refers to the root of a mount
+ * or not.
+ *
+ * Minimum Linux version required is v5.8.
+ */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "tst_test.h"
+#include "lapi/stat.h"
+
+#define MNTPOINT "mntpoint"
+#define TESTFILE MNTPOINT"/testfile"
+
+static int dir_fd = -1, file_fd = -1;
+
+static struct tcase {
+ const char *path;
+ bool mnt_root;
+ int *fd;
+} tcases[] = {
+ {MNTPOINT, 1, &dir_fd},
+ {TESTFILE, 0, &file_fd}
+};
+
+static void verify_statx(unsigned int n)
+{
+ struct tcase *tc = &tcases[n/2];
+ struct statx buf;
+ bool flag = n % 2;
+
+ if (flag) {
+ tst_res(TINFO, "Testing %s with STATX_ATTR_MOUNT_ROOT by fd",
+ tc->path);
+ TST_EXP_PASS_SILENT(statx(*tc->fd, "", AT_EMPTY_PATH, 0, &buf));
+ } else {
+ tst_res(TINFO, "Testing %s with STATX_ATTR_MOUNT_ROOT by path",
+ tc->path);
+ TST_EXP_PASS_SILENT(statx(AT_FDCWD, tc->path, 0, 0, &buf));
+ }
+
+ if (!(buf.stx_attributes_mask & STATX_ATTR_MOUNT_ROOT)) {
+ tst_res(TCONF, "Filesystem does not support STATX_ATTR_MOUNT_ROOT");
+ return;
+ }
+
+ if (buf.stx_attributes & STATX_ATTR_MOUNT_ROOT) {
+ tst_res(tc->mnt_root ? TPASS : TFAIL,
+ "STATX_ATTR_MOUNT_ROOT flag is set");
+ } else {
+ tst_res(tc->mnt_root ? TFAIL : TPASS,
+ "STATX_ATTR_MOUNT_ROOT flag is not set");
+ }
+}
+
+static void setup(void)
+{
+ SAFE_CREAT(TESTFILE, 0755);
+ dir_fd = SAFE_OPEN(MNTPOINT, O_DIRECTORY);
+ file_fd = SAFE_OPEN(TESTFILE, O_RDWR);
+}
+
+static void cleanup(void)
+{
+ if (dir_fd > -1)
+ SAFE_CLOSE(dir_fd);
+
+ if (file_fd > -1)
+ SAFE_CLOSE(file_fd);
+}
+
+static struct tst_test test = {
+ .test = verify_statx,
+ .setup = setup,
+ .cleanup = cleanup,
+ .mntpoint = MNTPOINT,
+ .mount_device = 1,
+ .all_filesystems = 1,
+ .needs_root = 1,
+ .tcnt = 2 * ARRAY_SIZE(tcases)
+};
diff --git a/testcases/kernel/syscalls/switch/endian_switch01.c b/testcases/kernel/syscalls/switch/endian_switch01.c
index bee35184a..fac9e2382 100644
--- a/testcases/kernel/syscalls/switch/endian_switch01.c
+++ b/testcases/kernel/syscalls/switch/endian_switch01.c
@@ -2,7 +2,7 @@
/*
* Copyright (c) International Business Machines Corp., 2008
* Copyright (c) Paul Mackerras, IBM Corp., 2008
- * Copyright (c) 2018 Linux Test Project
+ * Copyright (c) 2018-2023 Linux Test Project
*/
/*
@@ -17,14 +17,17 @@
#include <elf.h>
#include <sys/types.h>
#include <sys/wait.h>
+
#include "tst_test.h"
#if defined(__powerpc64__) || defined(__powerpc__)
+
# ifndef PPC_FEATURE_TRUE_LE
-# define PPC_FEATURE_TRUE_LE 0x00000002
+# define PPC_FEATURE_TRUE_LE 0x00000002
# endif
-# define TST_NO_DEFAULT_MAIN
+# ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
/*
* Make minimal call to 0x1ebe. If we get ENOSYS then syscall is not
@@ -42,6 +45,9 @@ void check_le_switch_supported(void)
exit(errno);
}
+ if (!(getauxval(AT_HWCAP) & PPC_FEATURE_TRUE_LE))
+ tst_brk(TCONF, "Processor does not support little-endian mode");
+
SAFE_WAIT(&status);
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
@@ -96,18 +102,9 @@ static struct tst_test test = {
.forks_child = 1,
};
-int main4(int argc, char **argv, LTP_ATTRIBUTE_UNUSED char **envp,
- unsigned long *auxv)
-{
- for (; *auxv != AT_NULL && *auxv != AT_HWCAP; auxv += 2)
- ;
-
- if (!(auxv[0] == AT_HWCAP && (auxv[1] & PPC_FEATURE_TRUE_LE)))
- tst_brk(TCONF, "Processor does not support little-endian mode");
-
- tst_run_tcases(argc, argv, &test);
- return 0;
-}
+# else
+TST_TEST_TCONF("Toolchain does not have <sys/auxv.h>");
+# endif /* HAVE_GETAUXVAL */
#else /* defined (__powerpc64__) || (__powerpc__) */
TST_TEST_TCONF("This system does not support running of switch() syscall");
diff --git a/testcases/kernel/syscalls/symlink/symlink01.c b/testcases/kernel/syscalls/symlink/symlink01.c
index eba64f9bd..8cf0c8f1c 100644
--- a/testcases/kernel/syscalls/symlink/symlink01.c
+++ b/testcases/kernel/syscalls/symlink/symlink01.c
@@ -658,10 +658,10 @@ int creat_symlink(char *path1, char *path2, char *_path3)
path1, errno, strerror(errno));
return 0;
} else {
- sprintf(Buf, "symlink(%s, %s) was succesful.\n", path1, path2);
+ sprintf(Buf, "symlink(%s, %s) was successful.\n", path1, path2);
strcat(Buffer, Buf);
#if DEBUG
- tst_resm(TPASS, "symlink(%s, %s) was succesful.", path1, path2);
+ tst_resm(TPASS, "symlink(%s, %s) was successful.", path1, path2);
#endif
}
return 1;
@@ -685,10 +685,10 @@ int creat_object(char *path1, char *_path2, char *_path3)
path1, errno, strerror(errno));
return 0;
} else {
- sprintf(Buf, "creat(%s, %#o) was succesful.\n", path1, MODE);
+ sprintf(Buf, "creat(%s, %#o) was successful.\n", path1, MODE);
strcat(Buffer, Buf);
#if DEBUG
- tst_resm(TPASS, "creat(%s, %#o) was succesful.", path1, MODE);
+ tst_resm(TPASS, "creat(%s, %#o) was successful.", path1, MODE);
#endif
}
if (close(fd) == -1) {
diff --git a/testcases/kernel/syscalls/timerfd/timerfd_create01.c b/testcases/kernel/syscalls/timerfd/timerfd_create01.c
index 3d70b84f0..18a233586 100644
--- a/testcases/kernel/syscalls/timerfd/timerfd_create01.c
+++ b/testcases/kernel/syscalls/timerfd/timerfd_create01.c
@@ -1,95 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014 Fujitsu Ltd.
- * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
- *
- * 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 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Zeng Linggang <zenglg.jy@cn.fujitsu.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * DESCRIPTION
- * Verify that,
- * 1. The clockid argument is neither CLOCK_MONOTONIC nor CLOCK_REALTIME,
- * EINVAL would return.
- * 2. flags is invalid, EINVAL would return.
+/*\
+ * [Description]
+ *
+ * This test verifies that:
+ * - clockid argument is neither CLOCK_MONOTONIC nor CLOCK_REALTIME,
+ * EINVAL would return.
+ * - flags is invalid, EINVAL would return.
*/
-#define _GNU_SOURCE
-
#include <errno.h>
-#include "test.h"
-#include "lapi/timerfd.h"
-
-char *TCID = "timerfd_create01";
+#include "tst_test.h"
+#include "tst_safe_timerfd.h"
static struct test_case_t {
int clockid;
int flags;
int exp_errno;
-} test_cases[] = {
- {-1, 0, EINVAL},
- {0, -1, EINVAL},
+} tcases[] = {
+ { -1, 0, EINVAL },
+ { 0, -1, EINVAL },
};
-int TST_TOTAL = ARRAY_SIZE(test_cases);
-static void setup(void);
-static void timerfd_create_verify(const struct test_case_t *);
-static void cleanup(void);
-
-int main(int argc, char *argv[])
+static void run(unsigned int i)
{
- int lc;
- int i;
-
- tst_parse_opts(argc, argv, NULL, NULL);
+ struct test_case_t *test = &tcases[i];
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- for (i = 0; i < TST_TOTAL; i++)
- timerfd_create_verify(&test_cases[i]);
- }
-
- cleanup();
- tst_exit();
+ TST_EXP_FAIL(timerfd_create(test->clockid, test->flags), test->exp_errno);
}
-static void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-}
-
-static void timerfd_create_verify(const struct test_case_t *test)
-{
- TEST(timerfd_create(test->clockid, test->flags));
-
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "timerfd_create() succeeded unexpectedly");
- return;
- }
-
- if (TEST_ERRNO == test->exp_errno) {
- tst_resm(TPASS | TTERRNO,
- "timerfd_create() failed as expected");
- } else {
- tst_resm(TFAIL | TTERRNO,
- "timerfd_create() failed unexpectedly; expected: "
- "%d - %s", test->exp_errno, strerror(test->exp_errno));
- }
-}
-
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/uname/uname04.c b/testcases/kernel/syscalls/uname/uname04.c
index 2d0851c8b..885368c24 100644
--- a/testcases/kernel/syscalls/uname/uname04.c
+++ b/testcases/kernel/syscalls/uname/uname04.c
@@ -79,4 +79,8 @@ static void run(unsigned int test_nr)
static struct tst_test test = {
.test = run,
.tcnt = 2,
+ .tags = (const struct tst_tag[]) {
+ {"CVE", "2012-0957"},
+ {}
+ }
};
diff --git a/testcases/kernel/syscalls/utils/compat_uid.h b/testcases/kernel/syscalls/utils/compat_uid.h
index 94e54f310..7a345a654 100644
--- a/testcases/kernel/syscalls/utils/compat_uid.h
+++ b/testcases/kernel/syscalls/utils/compat_uid.h
@@ -26,7 +26,7 @@
#include "tst_common.h"
#ifdef TST_USE_COMPAT16_SYSCALL
-typedef __kernel_old_uid_t UID_T;
+typedef unsigned short UID_T;
int UID_SIZE_CHECK(uid_t uid)
{
/* See high2lowuid in linux/highuid.h
diff --git a/testcases/kernel/syscalls/utils/ioprio.h b/testcases/kernel/syscalls/utils/ioprio.h
deleted file mode 100644
index 07220945c..000000000
--- a/testcases/kernel/syscalls/utils/ioprio.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __IOPRIO_H__
-#define __IOPRIO_H__
-
-//----------------------------------------------------------------------------
-// Copy of the 2.6.18 kernel header (linux/ioprio.h)
-//
-
-/*
- * Gives us 8 prio classes with 13-bits of data for each class
- */
-#define IOPRIO_BITS (16)
-#define IOPRIO_CLASS_SHIFT (13)
-#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
-
-#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
-#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
-#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
-
-#define ioprio_valid(mask) (IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE)
-
-/*
- * These are the io priority groups as implemented by CFQ. RT is the realtime
- * class, it always gets premium service. BE is the best-effort scheduling
- * class, the default for any process. IDLE is the idle scheduling class, it
- * is only served when no one else is using the disk.
- */
-enum {
- IOPRIO_CLASS_NONE,
- IOPRIO_CLASS_RT,
- IOPRIO_CLASS_BE,
- IOPRIO_CLASS_IDLE,
-};
-
-/*
- * 8 best effort priority levels are supported
- */
-#define IOPRIO_BE_NR (8)
-
-enum {
- IOPRIO_WHO_PROCESS = 1,
- IOPRIO_WHO_PGRP,
- IOPRIO_WHO_USER,
-};
-//-----------------------------------------------------------------------------
-
-#endif /* __IOPRIO_H__ */
diff --git a/testcases/kernel/syscalls/utime/utime02.c b/testcases/kernel/syscalls/utime/utime02.c
index 54693899e..fdcd40f66 100644
--- a/testcases/kernel/syscalls/utime/utime02.c
+++ b/testcases/kernel/syscalls/utime/utime02.c
@@ -11,6 +11,7 @@
* Verify that the system call utime() successfully changes the last
* access and modification times of a file to the current time,
* under the following constraints:
+ *
* - The times argument is NULL.
* - The user ID of the process is not "root".
* - The file is owned by the user ID of the process.
diff --git a/testcases/kernel/syscalls/utime/utime04.c b/testcases/kernel/syscalls/utime/utime04.c
index 67e40127d..7b820ab06 100644
--- a/testcases/kernel/syscalls/utime/utime04.c
+++ b/testcases/kernel/syscalls/utime/utime04.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2001
- * 07/2001 ported by John George
- * Copyright (c) 2022 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 ported by John George
+ * Copyright (c) 2022 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
/*\
@@ -11,6 +11,7 @@
* Verify that the system call utime() successfully changes the last
* access and modification times of a file to the values specified by
* times argument, under the following constraints:
+ *
* - The times argument is not NULL.
* - The user ID of the process is "root".
*/
diff --git a/testcases/kernel/syscalls/utime/utime05.c b/testcases/kernel/syscalls/utime/utime05.c
index ce0aa5dbf..941a3ccee 100644
--- a/testcases/kernel/syscalls/utime/utime05.c
+++ b/testcases/kernel/syscalls/utime/utime05.c
@@ -11,6 +11,7 @@
* Verify that the system call utime() successfully changes the last
* access and modification times of a file to the values specified by
* times argument, under the following constraints:
+ *
* - The times argument is not NULL.
* - The user ID of the process is not "root".
* - The file is owned by the user ID of the process.
diff --git a/testcases/kernel/syscalls/utime/utime06.c b/testcases/kernel/syscalls/utime/utime06.c
index 9057c29da..3ba62a316 100644
--- a/testcases/kernel/syscalls/utime/utime06.c
+++ b/testcases/kernel/syscalls/utime/utime06.c
@@ -9,11 +9,12 @@
* [Description]
*
* Verify that system call utime() fails with
- * - EACCES when times argument is NULL and user does not have rights
- * to modify the file.
+ *
+ * - EACCES when times argument is NULL and user does not have rights to modify
+ * the file.
* - ENOENT when specified file does not exist.
- * - EPERM when times argument is not NULL and user does not have rights
- * to modify the file.
+ * - EPERM when times argument is not NULL and user does not have rights to
+ * modify the file.
* - EROFS when the path resides on a read-only filesystem.
*/
diff --git a/testcases/kernel/syscalls/utimensat/utimensat01.c b/testcases/kernel/syscalls/utimensat/utimensat01.c
index 71a0e8d0e..efcb5c7a4 100644
--- a/testcases/kernel/syscalls/utimensat/utimensat01.c
+++ b/testcases/kernel/syscalls/utimensat/utimensat01.c
@@ -233,7 +233,7 @@ static void run(unsigned int i)
dfd = SAFE_OPEN(TEST_DIR, tc->oflags);
if (tc->pathname) {
- fd = SAFE_OPEN(tc->pathname, O_WRONLY | O_CREAT);
+ fd = SAFE_OPEN(tc->pathname, O_WRONLY | O_CREAT, 0200);
pathname = tc->pathname;
SAFE_CHMOD(tc->pathname, tc->mode);
reset_time(pathname, dfd, tc->flags, i);
diff --git a/testcases/kernel/syscalls/write/write02.c b/testcases/kernel/syscalls/write/write02.c
index 2f630ab65..ab38dce77 100644
--- a/testcases/kernel/syscalls/write/write02.c
+++ b/testcases/kernel/syscalls/write/write02.c
@@ -2,27 +2,24 @@
/*
* Copyright (c) 2017 Carlo Marcelo Arenas Belon <carlo@gmail.com>
* Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2003-2023
*/
-/*
+
+/*\
+ * [Description]
+ *
* Tests for a special case NULL buffer with size 0 is expected to return 0.
*/
-#include <errno.h>
#include "tst_test.h"
static int fd;
static void verify_write(void)
{
- TEST(write(fd, NULL, 0));
-
- if (TST_RET != 0) {
- tst_res(TFAIL | TTERRNO,
- "write() should have succeeded with ret=0");
- return;
- }
+ TST_EXP_POSITIVE(write(fd, NULL, 0));
- tst_res(TPASS, "write(fd, NULL, 0) == 0");
+ TST_EXP_EXPR(TST_RET == 0, "write(fd, NULL, %ld) == %d", TST_RET, 0);
}
static void setup(void)
diff --git a/testcases/kernel/syscalls/write/write04.c b/testcases/kernel/syscalls/write/write04.c
index afbac0f09..a5d62e0f5 100644
--- a/testcases/kernel/syscalls/write/write04.c
+++ b/testcases/kernel/syscalls/write/write04.c
@@ -28,7 +28,7 @@ static void verify_write(void)
{
char wbuf[8 * page_size];
- TST_EXP_FAIL(write(wfd, wbuf, sizeof(wbuf)), EAGAIN);
+ TST_EXP_FAIL2(write(wfd, wbuf, sizeof(wbuf)), EAGAIN);
}
static void setup(void)
diff --git a/testcases/kernel/syscalls/write/write05.c b/testcases/kernel/syscalls/write/write05.c
index 79769621c..b907624a8 100644
--- a/testcases/kernel/syscalls/write/write05.c
+++ b/testcases/kernel/syscalls/write/write05.c
@@ -1,19 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- * 07/2001 Ported by John George
- * 04/2002 wjhuie sigset cleanups
- * 08/2007 Ricardo Salveti de Araujo <rsalveti@linux.vnet.ibm.com>
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by John George
+ * 04/2002 wjhuie sigset cleanups
+ * 08/2007 Ricardo Salveti de Araujo <rsalveti@linux.vnet.ibm.com>
+ * Copyright (c) Linux Test Project, 2002-2023
*/
-/*
- * DESCRIPTION
+/*\
+ * [Description]
+ *
* Check the return value, and errnos of write(2)
+ *
* - when the file descriptor is invalid - EBADF
* - when the buf parameter is invalid - EFAULT
* - on an attempt to write to a pipe that is not open for reading - EPIPE
*/
+
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -42,7 +45,7 @@ static struct tcase {
{&pipefd[1], &buf, sizeof(buf), EPIPE},
};
-static int sigpipe_cnt;
+static volatile int sigpipe_cnt;
static void sighandler(int sig)
{
@@ -56,26 +59,12 @@ static void verify_write(unsigned int i)
sigpipe_cnt = 0;
- TEST(write(*tc->fd, *tc->buf, tc->size));
-
- if (TST_RET != -1) {
- tst_res(TFAIL, "write() succeeded unexpectedly");
- return;
- }
-
- if (TST_ERR != tc->exp_errno) {
- tst_res(TFAIL | TTERRNO,
- "write() failed unexpectedly, expected %s",
- tst_strerrno(tc->exp_errno));
+ TST_EXP_FAIL2(write(*tc->fd, *tc->buf, tc->size), tc->exp_errno);
+ if (TST_RET != -1)
return;
- }
- if (tc->exp_errno == EPIPE && sigpipe_cnt != 1) {
+ if (tc->exp_errno == EPIPE && sigpipe_cnt != 1)
tst_res(TFAIL, "sigpipe_cnt = %i", sigpipe_cnt);
- return;
- }
-
- tst_res(TPASS | TTERRNO, "write() failed expectedly");
}
static void setup(void)
diff --git a/testcases/lib/.gitignore b/testcases/lib/.gitignore
index 34dea272d..e8afd06f3 100644
--- a/testcases/lib/.gitignore
+++ b/testcases/lib/.gitignore
@@ -3,17 +3,23 @@
/tst_check_kconfigs
/tst_checkpoint
/tst_device
+/tst_fsfreeze
/tst_getconf
/tst_get_free_pids
/tst_get_median
/tst_get_unused_port
+/tst_hexdump
/tst_kvcmp
+/tst_lockdown_enabled
/tst_net_iface_prefix
/tst_net_ip_prefix
/tst_net_vars
+/tst_ns_create
+/tst_ns_exec
+/tst_ns_ifmove
/tst_random
/tst_rod
+/tst_secureboot_enabled
/tst_sleep
/tst_supported_fs
-/tst_hexdump
/tst_timeout_kill
diff --git a/testcases/lib/Makefile b/testcases/lib/Makefile
index f4f8c8524..990b46089 100644
--- a/testcases/lib/Makefile
+++ b/testcases/lib/Makefile
@@ -12,6 +12,7 @@ MAKE_TARGETS := tst_sleep tst_random tst_checkpoint tst_rod tst_kvcmp\
tst_device tst_net_iface_prefix tst_net_ip_prefix tst_net_vars\
tst_getconf tst_supported_fs tst_check_drivers tst_get_unused_port\
tst_get_median tst_hexdump tst_get_free_pids tst_timeout_kill\
- tst_check_kconfigs tst_cgctl
+ tst_check_kconfigs tst_cgctl tst_fsfreeze tst_ns_create tst_ns_exec\
+ tst_ns_ifmove tst_lockdown_enabled tst_secureboot_enabled
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/lib/tst_fsfreeze.c b/testcases/lib/tst_fsfreeze.c
new file mode 100644
index 000000000..4b0b12cba
--- /dev/null
+++ b/testcases/lib/tst_fsfreeze.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2010 Hajime Taira <htaira@redhat.com>
+ * Masatake Yamato <yamato@redhat.com>
+ * Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+ *
+ * Based on fsfreeze from util-linux.
+ */
+
+#include <linux/fs.h>
+#include <stdio.h>
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_safe_macros.h"
+
+static void help(void)
+{
+ printf("Freeze and unfreeze the device.\n");
+ printf("Usage: tst_fsfreeze device\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+
+ if (argc < 2) {
+ help();
+ return 1;
+ }
+
+ fd = SAFE_OPEN(argv[1], O_RDONLY);
+ SAFE_IOCTL(fd, FIFREEZE, 0);
+ SAFE_IOCTL(fd, FITHAW, 0);
+ SAFE_CLOSE(fd);
+
+ return 0;
+}
diff --git a/testcases/lib/tst_get_free_pids.c b/testcases/lib/tst_get_free_pids.c
index d7b68c620..370ec3e26 100644
--- a/testcases/lib/tst_get_free_pids.c
+++ b/testcases/lib/tst_get_free_pids.c
@@ -2,7 +2,7 @@
#define TST_NO_DEFAULT_MAIN
#include <stdio.h>
-#include <tst_test.h>
+#include "tst_test.h"
extern struct tst_test *tst_test;
diff --git a/testcases/lib/tst_kvcmp.c b/testcases/lib/tst_kvcmp.c
index 0f5793ef1..afc4b5ce3 100644
--- a/testcases/lib/tst_kvcmp.c
+++ b/testcases/lib/tst_kvcmp.c
@@ -7,7 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
-#include <tst_test.h>
+#include "tst_test.h"
enum op {
EQ,
diff --git a/testcases/lib/tst_lockdown_enabled.c b/testcases/lib/tst_lockdown_enabled.c
new file mode 100644
index 000000000..30abe3e5e
--- /dev/null
+++ b/testcases/lib/tst_lockdown_enabled.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+ */
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+
+int main(void)
+{
+ return tst_lockdown_enabled() <= 0;
+}
diff --git a/testcases/lib/tst_net.sh b/testcases/lib/tst_net.sh
index e6bb09d81..6168db86b 100644
--- a/testcases/lib/tst_net.sh
+++ b/testcases/lib/tst_net.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2014-2017 Oracle and/or its affiliates. All Rights Reserved.
-# Copyright (c) 2016-2022 Petr Vorel <pvorel@suse.cz>
+# Copyright (c) 2016-2023 Petr Vorel <pvorel@suse.cz>
# Author: Alexey Kodanev <alexey.kodanev@oracle.com>
[ -n "$TST_LIB_NET_LOADED" ] && return 0
@@ -59,7 +59,7 @@ tst_net_remote_tmpdir()
tst_net_setup()
{
- [ "$TST_IPVER" = 6 ] && tst_net_require_ipv6
+ [ "$TST_IPV6" ] && tst_net_require_ipv6
tst_net_remote_tmpdir
[ -n "$TST_SETUP_CALLER" ] && $TST_SETUP_CALLER
@@ -73,52 +73,93 @@ tst_net_setup()
fi
}
-if [ "$TST_PARSE_ARGS_CALLER" = "$TST_PARSE_ARGS" ]; then
- tst_res TWARN "TST_PARSE_ARGS_CALLER same as TST_PARSE_ARGS, unset it ($TST_PARSE_ARGS)"
- unset TST_PARSE_ARGS_CALLER
-fi
-if [ "$TST_SETUP_CALLER" = "$TST_SETUP" ]; then
- tst_res TWARN "TST_SETUP_CALLER same as TST_SETUP, unset it ($TST_SETUP)"
- unset TST_SETUP_CALLER
-fi
-if [ "$TST_USAGE_CALLER" = "$TST_USAGE" ]; then
- tst_res TWARN "TST_USAGE_CALLER same as TST_USAGE, unset it ($TST_USAGE)"
- unset TST_USAGE_CALLER
-fi
-
-if [ -n "$TST_USE_LEGACY_API" ]; then
- tst_net_read_opts "$@"
-fi
-
# old vs. new API compatibility layer
tst_res_()
{
[ -z "$TST_USE_LEGACY_API" ] && tst_res $@ || tst_resm $@
}
+
tst_brk_()
{
[ -z "$TST_USE_LEGACY_API" ] && tst_brk $@ || tst_brkm $@
}
+# Detect IPv6 disabled via 1) CONFIG_IPV6=n or 2) ipv6.disable=1 kernel cmdline
+# parameter or 3) sysctl net.ipv6.conf.all.disable_ipv6=1 (disables IPv6 on all
+# interfaces (including both already created and later created).
+# $TST_NET_IPV6_ENABLED: 1 on IPv6 enabled, 0 on IPv6 disabled.
tst_net_detect_ipv6()
{
local type="${1:-lhost}"
local cmd='[ -f /proc/net/if_inet6 ]'
- local ret
+ local disabled iface ret
if [ "$type" = "lhost" ]; then
$cmd
else
tst_rhost_run -c "$cmd"
fi
- ret=$?
- if [ $ret -eq 0 ]; then
- TST_NET_IPV6_ENABLED=1
+ if [ $? -ne 0 ]; then
+ TST_NET_IPV6_ENABLED=0
+ tst_res_ TINFO "IPv6 disabled on $type via kernel command line or not compiled in"
+ return
+ fi
+
+ cmd='cat /proc/sys/net/ipv6/conf/all/disable_ipv6'
+ if [ "$type" = "lhost" ]; then
+ disabled=$($cmd)
+ else
+ disabled=$(tst_rhost_run -c "$cmd")
+ fi
+ if [ $disabled = 1 ]; then
+ tst_res_ TINFO "IPv6 disabled on $type net.ipv6.conf.all.disable_ipv6=1"
+ TST_NET_IPV6_ENABLED=0
+ return
+ fi
+
+ TST_NET_IPV6_ENABLED=1
+}
+
+# Detect IPv6 disabled on interface via sysctl
+# net.ipv6.conf.$iface.disable_ipv6=1.
+# $TST_NET_IPV6_ENABLED: 1 on IPv6 enabled, 0 on IPv6 disabled.
+# return: 0 on IPv6 enabled, 1 on IPv6 disabled.
+tst_net_detect_ipv6_iface()
+{
+ [ "$TST_NET_IPV6_ENABLED" = 1 ] || return 1
+
+ local iface="$1"
+ local type="${2:-lhost}"
+ local check="cat /proc/sys/net/ipv6/conf/$iface/disable_ipv6"
+ local disabled
+
+ if [ "$type" = "lhost" ]; then
+ disabled=$($check)
else
+ disabled=$(tst_rhost_run -c "$check")
+ fi
+ if [ $disabled = 1 ]; then
+ tst_res_ TINFO "IPv6 disabled on $type on $iface"
TST_NET_IPV6_ENABLED=0
- tst_res TINFO "IPv6 disabled on $type"
+ return 1
fi
+
+ return 0
+}
+
+# Detect IPv6 disabled on used interfaces.
+tst_net_check_ifaces_ipv6()
+{
+ local iface
+
+ for iface in $(tst_get_ifaces); do
+ tst_net_detect_ipv6_iface $iface || return
+ done
+
+ for iface in $(tst_get_ifaces rhost); do
+ tst_net_detect_ipv6_iface $iface rhost || return
+ done
}
tst_net_require_ipv6()
@@ -131,18 +172,18 @@ init_ltp_netspace()
local pid
if [ ! -f /var/run/netns/ltp_ns -a -z "$LTP_NETNS" ]; then
- tst_require_cmds ip ns_create ns_exec ns_ifmove
+ tst_require_cmds ip tst_ns_create tst_ns_exec tst_ns_ifmove
tst_require_root
tst_require_drivers veth
ROD ip link add name ltp_ns_veth1 type veth peer name ltp_ns_veth2
- pid="$(ROD ns_create net,mnt)"
+ pid="$(ROD tst_ns_create net,mnt)"
mkdir -p /var/run/netns
ROD ln -s /proc/$pid/ns/net /var/run/netns/ltp_ns
- ROD ns_exec $pid net,mnt mount --make-rprivate /sys
- ROD ns_exec $pid net,mnt mount -t sysfs none /sys
- ROD ns_ifmove ltp_ns_veth1 $pid
- ROD ns_exec $pid net,mnt ip link set lo up
+ ROD tst_ns_exec $pid net,mnt mount --make-rprivate /sys
+ ROD tst_ns_exec $pid net,mnt mount -t sysfs none /sys
+ ROD tst_ns_ifmove ltp_ns_veth1 $pid
+ ROD tst_ns_exec $pid net,mnt ip link set lo up
elif [ -n "$LTP_NETNS" ]; then
tst_res_ TINFO "using not default LTP netns: '$LTP_NETNS'"
fi
@@ -150,10 +191,8 @@ init_ltp_netspace()
LHOST_IFACES="${LHOST_IFACES:-ltp_ns_veth2}"
RHOST_IFACES="${RHOST_IFACES:-ltp_ns_veth1}"
- export TST_INIT_NETNS="no"
-
pid="$(echo $(readlink /var/run/netns/ltp_ns) | cut -f3 -d'/')"
- export LTP_NETNS="${LTP_NETNS:-ns_exec $pid net,mnt}"
+ export LTP_NETNS="${LTP_NETNS:-tst_ns_exec $pid net,mnt}"
tst_restore_ipaddr
tst_restore_ipaddr rhost
@@ -460,7 +499,7 @@ tst_ipaddr_un()
;;
m)
! tst_is_int "$OPTARG" || [ "$OPTARG" -lt 0 ]|| [ "$OPTARG" -gt $max_net_id ] && \
- tst_brk TBROK "tst_ipaddr_un: -m must be integer <0,$max_net_id> ($OPTARG)"
+ tst_brk_ TBROK "tst_ipaddr_un: -m must be integer <0,$max_net_id> ($OPTARG)"
[ "$OPTARG" -gt $max_net_id ] && \
tst_brk_ TBROK "tst_ipaddr_un: -m cannot be higher than $max_net_id ($OPTARG)"
max_host_id="$OPTARG"
@@ -481,16 +520,16 @@ tst_ipaddr_un()
! tst_is_int "$min_host_id" || ! tst_is_int "$max_host_id" || \
[ $min_host_id -lt 0 -o $min_host_id -gt $default_max ] || \
[ $max_host_id -lt 0 -o $max_host_id -gt $default_max ] && \
- tst_brk TBROK "tst_ipaddr_un: HOST_ID must be int in range <0,$default_max> ($min_host_id,$max_host_id)"
+ tst_brk_ TBROK "tst_ipaddr_un: HOST_ID must be int in range <0,$default_max> ($min_host_id,$max_host_id)"
! tst_is_int "$min_net_id" || ! tst_is_int "$max_net_id" || \
[ $min_net_id -lt 0 -o $min_net_id -gt $default_max ] || \
[ $max_net_id -lt 0 -o $max_net_id -gt $default_max ] && \
- tst_brk TBROK "tst_ipaddr_un: NET_ID must be int in range <0,$default_max> ($min_net_id,$max_net_id)"
+ tst_brk_ TBROK "tst_ipaddr_un: NET_ID must be int in range <0,$default_max> ($min_net_id,$max_net_id)"
[ $min_host_id -gt $max_host_id ] && \
- tst_brk TBROK "tst_ipaddr_un: max HOST_ID ($max_host_id) must be >= min HOST_ID ($min_host_id)"
+ tst_brk_ TBROK "tst_ipaddr_un: max HOST_ID ($max_host_id) must be >= min HOST_ID ($min_host_id)"
[ $min_net_id -gt $max_net_id ] && \
- tst_brk TBROK "tst_ipaddr_un: max NET_ID ($max_net_id) must be >= min NET_ID ($min_net_id)"
+ tst_brk_ TBROK "tst_ipaddr_un: max NET_ID ($max_net_id) must be >= min NET_ID ($min_net_id)"
# counter
host_range=$((max_host_id - min_host_id + 1))
@@ -533,7 +572,9 @@ tst_init_iface()
local type="${1:-lhost}"
local link_num="${2:-0}"
local iface="$(tst_iface $type $link_num)"
+
tst_res_ TINFO "initialize '$type' '$iface' interface"
+ tst_net_detect_ipv6_iface $iface $type
if [ "$type" = "lhost" ]; then
if ip xfrm state 1>/dev/null 2>&1; then
@@ -584,7 +625,7 @@ tst_add_ipaddr()
d) action="del" ;;
q) quiet=1 ;;
s) lsafe="ROD"; rsafe="-s" ;;
- *) tst_brk TBROK "tst_add_ipaddr: unknown option: $OPTARG" ;;
+ *) tst_brk_ TBROK "tst_add_ipaddr: unknown option: $OPTARG" ;;
esac
done
shift $((OPTIND - 1))
@@ -593,6 +634,8 @@ tst_add_ipaddr()
local link_num="${2:-0}"
local iface=$(tst_iface $type $link_num)
+ tst_net_detect_ipv6_iface $iface $type
+
if [ "$TST_IPV6" ]; then
dad="nodad"
[ "$type" = "lhost" ] && mask=$IPV6_LPREFIX || mask=$IPV6_RPREFIX
@@ -969,43 +1012,25 @@ tst_default_max_pkt()
echo "$((mtu + mtu / 10))"
}
-[ -n "$TST_USE_LEGACY_API" ] && . test.sh || . tst_test.sh
-
-# detect IPv6 support on lhost for tests which don't use test links
-tst_net_detect_ipv6
-
-[ -n "$TST_NET_SKIP_VARIABLE_INIT" ] && return 0
-
-# Management Link
-[ -z "$RHOST" ] && TST_USE_NETNS="yes"
-export RHOST="$RHOST"
-export PASSWD="${PASSWD:-}"
-# Don't use it in new tests, use tst_rhost_run() from tst_net.sh instead.
-export LTP_RSH="${LTP_RSH:-ssh -nq}"
-
-# Test Links
-# IPV{4,6}_{L,R}HOST can be set with or without prefix (e.g. IP or IP/prefix),
-# but if you use IP/prefix form, /prefix will be removed by tst_net_vars.
-IPV4_LHOST="${IPV4_LHOST:-10.0.0.2/24}"
-IPV4_RHOST="${IPV4_RHOST:-10.0.0.1/24}"
-IPV6_LHOST="${IPV6_LHOST:-fd00:1:1:1::2/64}"
-IPV6_RHOST="${IPV6_RHOST:-fd00:1:1:1::1/64}"
-
-# tst_net_ip_prefix
+# Setup LTP network.
+#
+# Used tools:
+# * tst_net_ip_prefix
# Strip prefix from IP address and save both If no prefix found sets
# default prefix.
-#
-# tst_net_iface_prefix reads prefix and interface from rtnetlink.
+# * tst_net_iface_prefix reads prefix and interface from rtnetlink.
# If nothing found sets default prefix value.
-#
-# tst_net_vars exports environment variables related to test links and
+# * tst_net_vars exports environment variables related to test links and
# networks that aren't reachable through the test links.
#
# For full list of exported environment variables see:
# tst_net_ip_prefix -h
# tst_net_iface_prefix -h
# tst_net_vars -h
-if [ -z "$_tst_net_parse_variables" ]; then
+tst_net_setup_network()
+{
+ tst_require_cmds tst_net_iface_prefix tst_net_ip_prefix tst_net_vars
+
eval $(tst_net_ip_prefix $IPV4_LHOST || echo "exit $?")
eval $(tst_net_ip_prefix -r $IPV4_RHOST || echo "exit $?")
@@ -1015,25 +1040,20 @@ if [ -z "$_tst_net_parse_variables" ]; then
eval $(tst_net_ip_prefix $IPV6_LHOST || echo "exit $?")
eval $(tst_net_ip_prefix -r $IPV6_RHOST || echo "exit $?")
fi
-fi
-[ -n "$TST_USE_NETNS" -a "$TST_INIT_NETNS" != "no" ] && init_ltp_netspace
+ tst_net_use_netns && init_ltp_netspace
-if [ -z "$_tst_net_parse_variables" ]; then
eval $(tst_net_iface_prefix $IPV4_LHOST || echo "exit $?")
eval $(tst_rhost_run -c 'tst_net_iface_prefix -r '$IPV4_RHOST \
|| echo "exit $?")
+ eval $(tst_net_vars $IPV4_LHOST/$IPV4_LPREFIX \
+ $IPV4_RHOST/$IPV4_RPREFIX || echo "exit $?")
if [ "$TST_NET_IPV6_ENABLED" = 1 ]; then
+ tst_net_check_ifaces_ipv6
eval $(tst_net_iface_prefix $IPV6_LHOST || echo "exit $?")
eval $(tst_rhost_run -c 'tst_net_iface_prefix -r '$IPV6_RHOST \
|| echo "exit $?")
- fi
-
- eval $(tst_net_vars $IPV4_LHOST/$IPV4_LPREFIX \
- $IPV4_RHOST/$IPV4_RPREFIX || echo "exit $?")
-
- if [ "$TST_NET_IPV6_ENABLED" = 1 ]; then
eval $(tst_net_vars $IPV6_LHOST/$IPV6_LPREFIX \
$IPV6_RHOST/$IPV6_RPREFIX || echo "exit $?")
fi
@@ -1043,9 +1063,56 @@ if [ -z "$_tst_net_parse_variables" ]; then
tst_res_ TINFO "$IPV4_LHOST/$IPV4_LPREFIX -- $IPV4_RHOST/$IPV4_RPREFIX"
tst_res_ TINFO "$IPV6_LHOST/$IPV6_LPREFIX -- $IPV6_RHOST/$IPV6_RPREFIX"
- export _tst_net_parse_variables="yes"
+ if [ -n "$TST_USE_LEGACY_API" ]; then
+ [ "$TST_IPV6" ] && tst_net_require_ipv6
+ tst_net_remote_tmpdir
+ fi
+}
+
+[ -n "$TST_USE_LEGACY_API" ] && . test.sh || . tst_test.sh
+
+if [ -n "$TST_USE_LEGACY_API" ]; then
+ tst_net_read_opts "$@"
+else
+ if [ "$TST_PARSE_ARGS_CALLER" = "$TST_PARSE_ARGS" ]; then
+ tst_res_ TWARN "TST_PARSE_ARGS_CALLER same as TST_PARSE_ARGS, unset it ($TST_PARSE_ARGS)"
+ unset TST_PARSE_ARGS_CALLER
+ fi
+ if [ "$TST_SETUP_CALLER" = "$TST_SETUP" ]; then
+ tst_res_ TWARN "TST_SETUP_CALLER same as TST_SETUP, unset it ($TST_SETUP)"
+ unset TST_SETUP_CALLER
+ fi
+ if [ "$TST_USAGE_CALLER" = "$TST_USAGE" ]; then
+ tst_res_ TWARN "TST_USAGE_CALLER same as TST_USAGE, unset it ($TST_USAGE)"
+ unset TST_USAGE_CALLER
+ fi
fi
+# detect IPv6 support on lhost for tests which don't use test links
+tst_net_detect_ipv6
+
+[ -n "$TST_NET_SKIP_VARIABLE_INIT" ] && return 0
+
+# Management Link
+[ -z "$RHOST" ] && TST_USE_NETNS="yes"
+export RHOST="$RHOST"
+export PASSWD="${PASSWD:-}"
+# Don't use it in new tests, use tst_rhost_run() from tst_net.sh instead.
+export LTP_RSH="${LTP_RSH:-ssh -nq}"
+
+# Test Links
+# IPV{4,6}_{L,R}HOST can be set with or without prefix (e.g. IP or IP/prefix),
+# but if you use IP/prefix form, /prefix will be removed by tst_net_vars.
+IPV4_LHOST="${IPV4_LHOST:-10.0.0.2/24}"
+IPV4_RHOST="${IPV4_RHOST:-10.0.0.1/24}"
+IPV6_LHOST="${IPV6_LHOST:-fd00:1:1:1::2/64}"
+IPV6_RHOST="${IPV6_RHOST:-fd00:1:1:1::1/64}"
+
+tst_net_setup_network
+
+# More information about network parameters can be found
+# in the following document: testcases/network/stress/README
+
export TST_NET_DATAROOT="$LTPROOT/testcases/bin/datafiles"
export TST_NETLOAD_CLN_REQUESTS="${TST_NETLOAD_CLN_REQUESTS:-10000}"
@@ -1090,13 +1157,6 @@ export RHOST_HWADDRS="${RHOST_HWADDRS:-$(tst_get_hwaddrs rhost)}"
export NS_ICMPV4_SENDER_DATA_MAXSIZE=1472
export NS_ICMPV6_SENDER_DATA_MAXSIZE=1452
-# More information about network parameters can be found
-# in the following document: testcases/network/stress/README
-
-if [ -n "$TST_USE_LEGACY_API" ]; then
- tst_net_remote_tmpdir
-fi
-
if [ -z "$TST_USE_LEGACY_API" ] && ! tst_cmd_available ping6; then
ping6()
{
diff --git a/testcases/kernel/containers/share/ns_common.h b/testcases/lib/tst_ns_common.h
index 813cd3388..358db5141 100644
--- a/testcases/kernel/containers/share/ns_common.h
+++ b/testcases/lib/tst_ns_common.h
@@ -3,8 +3,8 @@
* Copyright (c) Linux Test Project, 2015-2023
*/
-#ifndef __NS_COMMON_H__
-#define __NS_COMMON_H__
+#ifndef TST_NS_COMMON_H__
+#define TST_NS_COMMON_H__
#include <sched.h>
#include "lapi/sched.h"
@@ -39,4 +39,4 @@ static struct param *get_param(const char *name)
return NULL;
}
-#endif
+#endif /* TST_NS_COMMON_H__ */
diff --git a/testcases/lib/tst_ns_create.c b/testcases/lib/tst_ns_create.c
new file mode 100644
index 000000000..1c6258cd1
--- /dev/null
+++ b/testcases/lib/tst_ns_create.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2015 Red Hat, Inc.
+ * Matus Marhefka <mmarhefk@redhat.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ * Copyright (c) Linux Test Project, 2020-2023
+ */
+
+/*\
+ * [Description]
+ *
+ * Creates a child process in the new specified namespace(s), child is then
+ * daemonized and is running in the background. PID of the daemonized child
+ * process is printed on the stdout. As the new namespace(s) is(are) maintained
+ * by the daemonized child process it(they) can be removed by killing this
+ * process.
+ */
+
+#define TST_NO_DEFAULT_MAIN
+
+#include <stdio.h>
+#include <string.h>
+#include "tst_test.h"
+#include "tst_ns_common.h"
+
+extern struct tst_test *tst_test;
+
+static struct tst_test test = {
+ .forks_child = 1, /* Needed by SAFE_CLONE */
+};
+
+static void print_help(void)
+{
+ int i;
+
+ printf("usage: tst_ns_create <%s", params[0].name);
+
+ for (i = 1; params[i].name; i++)
+ printf("|,%s", params[i].name);
+
+ printf(">\n");
+}
+
+static void child_fn(void)
+{
+ int i;
+
+ SAFE_SETSID();
+ SAFE_CHDIR("/");
+
+ for (i = 0; i < SAFE_SYSCONF(_SC_OPEN_MAX); i++)
+ close(i);
+
+ printf("pausing child\n");
+ pause();
+}
+
+int main(int argc, char *argv[])
+{
+ struct tst_clone_args args = { 0, SIGCHLD };
+ char *token;
+ int pid;
+
+ if (argc < 2) {
+ print_help();
+ return 1;
+ }
+
+ tst_test = &test;
+
+ while ((token = strsep(&argv[1], ","))) {
+ struct param *p = get_param(token);
+
+ if (!p) {
+ printf("Unknown namespace: %s\n", token);
+ print_help();
+ return 1;
+ }
+
+ args.flags |= p->flag;
+ }
+
+ pid = SAFE_CLONE(&args);
+ if (!pid) {
+ child_fn();
+ return 0;
+ }
+
+ printf("%d", pid);
+
+ return 0;
+}
diff --git a/testcases/lib/tst_ns_exec.c b/testcases/lib/tst_ns_exec.c
new file mode 100644
index 000000000..66a4e69d3
--- /dev/null
+++ b/testcases/lib/tst_ns_exec.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2015 Red Hat, Inc.
+ * Matus Marhefka <mmarhefk@redhat.com>
+ * Copyright (c) Linux Test Project, 2015-2023
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Enters the namespace(s) of a process specified by a PID and then executes
+ * the indicated program inside that namespace(s).
+ */
+
+#define TST_NO_DEFAULT_MAIN
+
+#include <stdio.h>
+#include <sys/wait.h>
+#include "tst_test.h"
+#include "tst_ns_common.h"
+
+extern struct tst_test *tst_test;
+
+static struct tst_test test = {
+ .forks_child = 1, /* Needed by SAFE_CLONE */
+};
+
+static int ns_fd[NS_TOTAL];
+static int ns_fds;
+
+static void print_help(void)
+{
+ int i;
+
+ printf("usage: tst_ns_exec <NS_PID> <%s", params[0].name);
+
+ for (i = 1; params[i].name; i++)
+ printf("|,%s", params[i].name);
+
+ printf("> <PROGRAM> [ARGS]\nSecond argument indicates the types"
+ " of a namespaces maintained by NS_PID\nand is specified"
+ " as a comma separated list.\n"
+ "Example: tst_ns_exec 1234 net,ipc ip a\n");
+}
+
+static void open_ns_fd(const char *pid, const char *ns)
+{
+ int fd;
+ char file_buf[64];
+
+ sprintf(file_buf, "%s/%s/ns/%s", PROC_PATH, pid, ns);
+
+ fd = SAFE_OPEN(file_buf, O_RDONLY);
+ ns_fd[ns_fds] = fd;
+
+ ++ns_fds;
+}
+
+static void close_ns_fd(void)
+{
+ int i;
+
+ for (i = 0; i < ns_fds; i++)
+ SAFE_CLOSE(ns_fd[i]);
+}
+
+int main(int argc, char *argv[])
+{
+ struct tst_clone_args args = { 0, SIGCHLD };
+ int i, status, pid;
+ char *token;
+
+ tst_test = &test;
+
+ if (argc < 4) {
+ print_help();
+ return 1;
+ }
+
+ memset(ns_fd, 0, sizeof(ns_fd));
+
+ while ((token = strsep(&argv[2], ","))) {
+ struct param *p = get_param(token);
+
+ if (!p) {
+ printf("Unknown namespace: %s\n", token);
+ print_help();
+ return 1;
+ }
+
+ open_ns_fd(argv[1], token);
+ }
+
+ if (!ns_fds) {
+ printf("no namespace entries in /proc/%s/ns/\n", argv[1]);
+ return 1;
+ }
+
+ for (i = 0; i < ns_fds; i++)
+ SAFE_SETNS(ns_fd[i], 0);
+
+ pid = SAFE_CLONE(&args);
+ if (!pid)
+ SAFE_EXECVP(argv[3], argv+3);
+
+ SAFE_WAITPID(pid, &status, 0);
+
+ close_ns_fd();
+
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+
+ return 0;
+}
diff --git a/testcases/lib/tst_ns_ifmove.c b/testcases/lib/tst_ns_ifmove.c
new file mode 100644
index 000000000..03531fc9b
--- /dev/null
+++ b/testcases/lib/tst_ns_ifmove.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (c) 2015 Red Hat, Inc.
+ * Copyright (c) Linux Test Project, 2015-2022
+ * Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+ * Written by Matus Marhefka <mmarhefk@redhat.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Moves a network interface to the namespace of a process specified by a PID.
+ */
+
+#include "config.h"
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_safe_macros.h"
+#include "tst_safe_net.h"
+
+#include <linux/if.h>
+#include <linux/rtnetlink.h>
+#include <net/ethernet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_DECL_IFLA_NET_NS_PID
+
+static struct {
+ struct nlmsghdr nh;
+ struct ifinfomsg ifi;
+ char attrbuf[512];
+} req;
+
+
+static int get_intf_index_from_name(const char *intf_name)
+{
+ struct ifreq ifr;
+ int sock_fd;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, intf_name, sizeof(ifr.ifr_name) - 1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
+
+ sock_fd = SAFE_SOCKET(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+
+ /* interface index */
+ SAFE_IOCTL(sock_fd, SIOCGIFINDEX, &ifr);
+ SAFE_CLOSE(sock_fd);
+
+ return ifr.ifr_ifindex;
+}
+
+int main(int argc, char **argv)
+{
+ struct rtattr *rta;
+ int intf_index, pid, rtnetlink_socket;
+
+ if (argc != 3) {
+ printf("tst_ns_ifmove <INTERFACE_NAME> <NAMESPACE_PID>\n");
+ return 1;
+ }
+
+ intf_index = get_intf_index_from_name(argv[1]);
+ pid = atoi(argv[2]);
+ rtnetlink_socket = SAFE_SOCKET(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+
+ memset(&req, 0, sizeof(req));
+ req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.nh.nlmsg_flags = NLM_F_REQUEST;
+ req.nh.nlmsg_type = RTM_NEWLINK;
+ req.ifi.ifi_family = AF_UNSPEC;
+ req.ifi.ifi_index = intf_index;
+ req.ifi.ifi_change = 0xffffffff;
+ rta = (struct rtattr *)(((char *) &req) +
+ NLMSG_ALIGN(req.nh.nlmsg_len));
+ rta->rta_type = IFLA_NET_NS_PID;
+ rta->rta_len = RTA_LENGTH(sizeof(int));
+ req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) +
+ RTA_LENGTH(sizeof(pid));
+ memcpy(RTA_DATA(rta), &pid, sizeof(pid));
+
+ SAFE_SEND(1, rtnetlink_socket, &req, req.nh.nlmsg_len, 0);
+ SAFE_CLOSE(rtnetlink_socket);
+
+ return 0;
+}
+
+#else
+ TST_TEST_TCONF("IFLA_NET_NS_PID not defined in linux/if_link.h");
+#endif
diff --git a/testcases/lib/tst_secureboot_enabled.c b/testcases/lib/tst_secureboot_enabled.c
new file mode 100644
index 000000000..dadc0413c
--- /dev/null
+++ b/testcases/lib/tst_secureboot_enabled.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+ */
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+
+int main(void)
+{
+ return tst_secureboot_enabled() <= 0;
+}
diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh
index 3bd68a63a..b3f451a21 100644
--- a/testcases/lib/tst_test.sh
+++ b/testcases/lib/tst_test.sh
@@ -532,7 +532,7 @@ _tst_cleanup_timer()
{
if [ -n "$_tst_setup_timer_pid" ]; then
kill -TERM $_tst_setup_timer_pid 2>/dev/null
- # kill is succesful only on test timeout
+ # kill is successful only on test timeout
wait $_tst_setup_timer_pid 2>/dev/null || true
fi
}
@@ -682,7 +682,7 @@ tst_run()
CHECKPOINT_WAIT|CHECKPOINT_WAKE);;
CHECKPOINT_WAKE2|CHECKPOINT_WAKE_AND_WAIT);;
DEV_EXTRA_OPTS|DEV_FS_OPTS|FORMAT_DEVICE|MOUNT_DEVICE);;
- SKIP_FILESYSTEMS);;
+ SKIP_FILESYSTEMS|SKIP_IN_LOCKDOWN|SKIP_IN_SECUREBOOT);;
*) tst_res TWARN "Reserved variable TST_$_tst_i used!";;
esac
done
@@ -702,6 +702,14 @@ tst_run()
[ "$TST_NEEDS_ROOT" = 1 ] && tst_require_root
+ if [ "$TST_SKIP_IN_SECUREBOOT" = 1 ] && tst_secureboot_enabled; then
+ tst_brk TCONF "SecureBoot enabled, skipping test"
+ fi
+
+ if [ "$TST_SKIP_IN_LOCKDOWN" = 1 ] && tst_lockdown_enabled; then
+ tst_brk TCONF "Kernel is locked down, skipping test"
+ fi
+
[ "$TST_DISABLE_APPARMOR" = 1 ] && tst_disable_apparmor
[ "$TST_DISABLE_SELINUX" = 1 ] && tst_disable_selinux
@@ -726,6 +734,8 @@ tst_run()
fi
TST_TMPDIR=$(mktemp -d "$TMPDIR/LTP_$TST_ID.XXXXXXXXXX")
+ # remove possible trailing slash or double slashes from TMPDIR
+ TST_TMPDIR=$(echo "$TST_TMPDIR" | sed 's~/\+~/~g')
chmod 777 "$TST_TMPDIR"
diff --git a/testcases/network/iptables/iptables_lib.sh b/testcases/network/iptables/iptables_lib.sh
index ab76cbd41..767008869 100755
--- a/testcases/network/iptables/iptables_lib.sh
+++ b/testcases/network/iptables/iptables_lib.sh
@@ -22,7 +22,7 @@ NFRUN()
if [ "$use_iptables" = 1 ]; then
ip${TST_IPV6}tables $@
else
- $(ip${TST_IPV6}tables-translate $@ | sed 's,\\,,g')
+ $(ip${TST_IPV6}tables-translate $@ | sed "s/[\']//g")
fi
}
@@ -66,9 +66,9 @@ init()
cleanup()
{
if lsmod | grep -q "ip${TST_IPV6}_tables"; then
- NFTRUN -F -t filter > /dev/null 2>&1
- NFTRUN -F -t nat > /dev/null 2>&1
- NFTRUN -F -t mangle > /dev/null 2>&1
+ NFRUN -F -t filter > /dev/null 2>&1
+ NFRUN -F -t nat > /dev/null 2>&1
+ NFRUN -F -t mangle > /dev/null 2>&1
rmmod -v ipt_limit ipt_multiport ipt_LOG ipt_REJECT \
ip${TST_IPV6}table_mangle ip${TST_IPV6}table_nat ip_conntrack \
ip${TST_IPV6}table_filter ip${TST_IPV6}_tables nf_nat_ipv${TST_IPVER} nf_nat \
diff --git a/testcases/network/lib6/asapi_01.c b/testcases/network/lib6/asapi_01.c
index a34b8aee6..ac1de5418 100644
--- a/testcases/network/lib6/asapi_01.c
+++ b/testcases/network/lib6/asapi_01.c
@@ -33,7 +33,7 @@
#include "test.h"
#include "safe_macros.h"
-char *TCID = "asapi_04";
+char *TCID = "asapi_01";
static pid_t pid;
diff --git a/testcases/network/lib6/asapi_02.c b/testcases/network/lib6/asapi_02.c
index f8c30f1df..7808b2c3a 100644
--- a/testcases/network/lib6/asapi_02.c
+++ b/testcases/network/lib6/asapi_02.c
@@ -1,102 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2015 Fujitsu Ltd.
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
* Copyright (c) International Business Machines Corp., 2001
+ * Author: David L Stevens
+ */
+
+/*\
+ * [Description]
*
- * 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.
+ * Basic test for ICMP6_FILTER.
*
- * 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.
+ * For ICMP6_FILTER usage, refer to: https://man.openbsd.org/icmp6.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * Because of the extra functionality of ICMPv6 in comparison to ICMPv4, a
+ * larger number of messages may be potentially received on an ICMPv6 socket.
+ * Input filters may therefore be used to restrict input to a subset of the
+ * incoming ICMPv6 messages so only interesting messages are returned by the
+ * recv(2) family of calls to an application.
+
+ * The icmp6_filter structure may be used to refine the input message set
+ * according to the ICMPv6 type. By default, all messages types are allowed
+ * on newly created raw ICMPv6 sockets. The following macros may be used to
+ * refine the input set, thus being tested:
*
- * Author: David L Stevens
+ * void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *filterp)
+ * &ndash; Allow all incoming messages. filterp is modified to allow all message types.
+ *
+ * void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *filterp)
+ * &ndash; Ignore all incoming messages. filterp is modified to ignore all message types.
+ *
+ * void ICMP6_FILTER_SETPASS(int, struct icmp6_filter *filterp)
+ * &ndash; Allow ICMPv6 messages with the given type. filterp is modified to allow such
+ * messages.
+ *
+ * void ICMP6_FILTER_SETBLOCK(int, struct icmp6_filter *filterp)
+ * &ndash; Ignore ICMPv6 messages with the given type. filterp is modified to ignore
+ * such messages.
+ *
+ * int ICMP6_FILTER_WILLPASS(int, const struct icmp6_filter *filterp)
+ * &ndash; Determine if the given filter will allow an ICMPv6 message of the given type.
+ *
+ * int ICMP6_FILTER_WILLBLOCK(int, const struct icmp6_filter *)
+ * &ndash; Determine if the given filter will ignore an ICMPv6 message of the given type.
+ *
+ * The getsockopt(2) and setsockopt(2) calls may be used to obtain and install
+ * the filter on ICMPv6 sockets at option level IPPROTO_ICMPV6 and name ICMP6_FILTER
+ * with a pointer to the icmp6_filter structure as the option value.
*/
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/wait.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <netinet/ip6.h>
#include <netinet/icmp6.h>
+#include "tst_test.h"
-#include "test.h"
-#include "safe_macros.h"
+static int sall = -1, sf = -1;
-char *TCID = "asapi_05";
-
-static void setup(void);
-
-static void icmp6_ft(void);
-
-int main(int argc, char *argv[])
-{
- int lc;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); ++lc)
- icmp6_ft();
-
- tst_exit();
-}
-
-static void setup(void)
-{
- TEST_PAUSE;
- tst_require_root();
-}
-
-enum tt {
- T_WILLPASS,
- T_WILLBLOCK,
- T_SETPASS,
- T_SETBLOCK,
- T_SETPASSALL,
- T_SETBLOCKALL
+enum filter_macro {
+ FILTER_SETPASS,
+ FILTER_SETBLOCK,
+ FILTER_PASSALL,
+ FILTER_BLOCKALL,
+ FILTER_WILLBLOCK,
+ FILTER_WILLPASS
};
-static struct ftent {
- char *ft_tname; /* test name, for logging */
- unsigned char ft_sndtype; /* send type field */
- unsigned char ft_flttype; /* filter type field */
- enum tt ft_test; /* what macro to test */
- int ft_expected; /* packet should pass? */
-} ftab[] = {
- {"ICMP6_FILTER_SETPASS s 20 f 20", 20, 20, T_SETPASS, 1},
- {"ICMP6_FILTER_SETPASS s 20 f 21", 20, 21, T_SETPASS, 0},
- {"ICMP6_FILTER_SETBLOCK s 20 f 20", 20, 20, T_SETBLOCK, 0},
- {"ICMP6_FILTER_SETBLOCK s 20 f 21", 20, 21, T_SETBLOCK, 1},
- {"ICMP6_FILTER_PASSALL s 20", 20, 0, T_SETPASSALL, 1},
- {"ICMP6_FILTER_PASSALL s 20", 21, 0, T_SETPASSALL, 1},
- {"ICMP6_FILTER_BLOCKALL s 20", 20, 0, T_SETBLOCKALL, 0},
- {"ICMP6_FILTER_BLOCKALL s 20", 21, 0, T_SETBLOCKALL, 0},
- {"ICMP6_FILTER_WILLBLOCK s 20 f 21", 20, 21, T_WILLBLOCK, 0},
- {"ICMP6_FILTER_WILLBLOCK s 20 f 20", 20, 20, T_WILLBLOCK, 1},
- {"ICMP6_FILTER_WILLPASS s 20 f 21", 20, 21, T_WILLPASS, 0},
- {"ICMP6_FILTER_WILLPASS s 22 f 22", 22, 22, T_WILLPASS, 1},
+#define DESC(x, y, z) .tname = "ICMP6_" #x ", send type: " #y ", filter type: " \
+ #z, .send_type = y, .filter_type = z, .test_macro = x
+
+static struct tcase {
+ char *tname;
+ unsigned char send_type;
+ unsigned char filter_type;
+ enum filter_macro test_macro;
+ int pass_packet;
+} tcases[] = {
+ {DESC(FILTER_SETPASS, 20, 20), .pass_packet = 1},
+ {DESC(FILTER_SETPASS, 20, 21)},
+ {DESC(FILTER_SETBLOCK, 20, 20)},
+ {DESC(FILTER_SETBLOCK, 20, 21), .pass_packet = 1},
+ {DESC(FILTER_PASSALL, 20, 20), .pass_packet = 1},
+ {DESC(FILTER_PASSALL, 21, 0), .pass_packet = 1},
+ {DESC(FILTER_BLOCKALL, 20, 0)},
+ {DESC(FILTER_BLOCKALL, 21, 0)},
+ {DESC(FILTER_WILLBLOCK, 20, 21)},
+ {DESC(FILTER_WILLBLOCK, 20, 20), .pass_packet = 1},
+ {DESC(FILTER_WILLPASS, 20, 21)},
+ {DESC(FILTER_WILLPASS, 22, 22), .pass_packet = 1},
};
-#define FTCOUNT ARRAY_SIZE(ftab)
-
-static int ic6_send1(char *tname, unsigned char type)
+static void ic6_send(unsigned char type)
{
struct sockaddr_in6 sin6;
struct icmp6_hdr ic6;
int s;
- s = SAFE_SOCKET(NULL, AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+ s = SAFE_SOCKET(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
memset(&ic6, 0, sizeof(ic6));
ic6.icmp6_type = type;
@@ -105,22 +101,15 @@ static int ic6_send1(char *tname, unsigned char type)
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = in6addr_loopback;
- if (sendto(s, &ic6, sizeof(ic6), 0, (struct sockaddr *)&sin6,
- sizeof(sin6)) == -1) {
- tst_resm(TBROK | TERRNO, "%s: sendto failed", tname);
- return 1;
- }
- return 0;
+ SAFE_SENDTO(0, s, &ic6, sizeof(ic6), 0, (struct sockaddr *)&sin6, sizeof(sin6));
}
-static int ic6_recv1(char *tname, int sall, int sf)
+static int ic6_recv(void)
{
fd_set readfds, readfds_saved;
struct timeval tv;
- int maxfd, nfds;
- int gotall, gotone;
- int cc;
- static unsigned char rbuf[2048];
+ int maxfd, nfds, gotall, gotone;
+ unsigned char rbuf[2048];
tv.tv_sec = 0;
tv.tv_usec = 250000;
@@ -133,129 +122,120 @@ static int ic6_recv1(char *tname, int sall, int sf)
memcpy(&readfds, &readfds_saved, sizeof(readfds));
gotall = gotone = 0;
- /*
- * Note: this relies on linux-specific behavior (select
- * updating tv with time elapsed)
- */
+
while (!gotall || !gotone) {
struct icmp6_hdr *pic6 = (struct icmp6_hdr *)rbuf;
nfds = select(maxfd + 1, &readfds, 0, 0, &tv);
if (nfds == 0)
- break; /* timed out */
+ break;
+
if (nfds < 0) {
if (errno == EINTR)
continue;
- tst_resm(TBROK | TERRNO, "%s: select failed", tname);
+ tst_brk(TBROK | TERRNO, "select failed");
}
+
if (FD_ISSET(sall, &readfds)) {
- cc = recv(sall, rbuf, sizeof(rbuf), 0);
- if (cc < 0) {
- tst_resm(TBROK | TERRNO,
- "%s: recv(sall, ..) failed", tname);
- return -1;
- }
- /* if packet check succeeds... */
+ SAFE_RECV(0, sall, rbuf, sizeof(rbuf), 0);
if (htonl(pic6->icmp6_data32[0]) == (uint32_t)getpid())
gotall = 1;
}
+
if (FD_ISSET(sf, &readfds)) {
- cc = recv(sf, rbuf, sizeof(rbuf), 0);
- if (cc < 0) {
- tst_resm(TBROK | TERRNO,
- "%s: recv(sf, ..) failed", tname);
- return -1;
- }
- /* if packet check succeeds... */
+ SAFE_RECV(0, sf, rbuf, sizeof(rbuf), 0);
if (htonl(pic6->icmp6_data32[0]) == (uint32_t)getpid())
gotone = 1;
}
memcpy(&readfds, &readfds_saved, sizeof(readfds));
}
+
if (!gotall) {
- tst_resm(TBROK, "%s: recv all timed out", tname);
+ tst_res(TFAIL, "recv all time out");
return -1;
}
+
if (gotone)
return 1;
+
return 0;
}
-/* functional tests */
-static void icmp6_ft(void)
+static void verify_icmp6_filter(unsigned int n)
{
+ struct tcase *tc = &tcases[n];
struct icmp6_filter i6f;
- int sall, sf;
- unsigned int i;
+ int rc;
+
+ tst_res(TINFO, "Testing %s", tc->tname);
+
+ switch (tc->test_macro) {
+ case FILTER_SETPASS:
+ ICMP6_FILTER_SETBLOCKALL(&i6f);
+ ICMP6_FILTER_SETPASS(tc->filter_type, &i6f);
+ break;
+ case FILTER_PASSALL:
+ ICMP6_FILTER_SETPASSALL(&i6f);
+ break;
+ case FILTER_SETBLOCK:
+ ICMP6_FILTER_SETPASSALL(&i6f);
+ ICMP6_FILTER_SETBLOCK(tc->filter_type, &i6f);
+ break;
+ case FILTER_BLOCKALL:
+ ICMP6_FILTER_SETBLOCKALL(&i6f);
+ break;
+ case FILTER_WILLBLOCK:
+ ICMP6_FILTER_SETPASSALL(&i6f);
+ ICMP6_FILTER_SETBLOCK(tc->filter_type, &i6f);
+ rc = ICMP6_FILTER_WILLBLOCK(tc->send_type, &i6f);
+ TST_EXP_EXPR(rc == tc->pass_packet, "%d (%d)", tc->pass_packet, rc);
+ return;
+ case FILTER_WILLPASS:
+ ICMP6_FILTER_SETBLOCKALL(&i6f);
+ ICMP6_FILTER_SETPASS(tc->filter_type, &i6f);
+ rc = ICMP6_FILTER_WILLPASS(tc->send_type, &i6f);
+ TST_EXP_EXPR(rc == tc->pass_packet, "%d (%d)", tc->pass_packet, rc);
+ return;
+ default:
+ tst_brk(TBROK, "unknown test type %d", tc->filter_type);
+ break;
+ }
- sall = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+ SAFE_SETSOCKOPT(sf, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f, sizeof(i6f));
+ ic6_send(tc->send_type);
- ICMP6_FILTER_SETPASSALL(&i6f);
- if (setsockopt(sall, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f,
- sizeof(i6f)) < 0) {
- tst_resm(TBROK | TERRNO,
- "setsockopt pass all ICMP6_FILTER failed");
- }
+ rc = ic6_recv();
+ if (rc < 0)
+ return;
- sf = SAFE_SOCKET(NULL, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+ TST_EXP_EXPR(rc == tc->pass_packet, "%s packet type %d",
+ rc ? "pass" : "block", tc->send_type);
+}
- int rv;
+static void setup(void)
+{
+ struct icmp6_filter i6f;
- for (i = 0; i < FTCOUNT; ++i) {
+ sall = SAFE_SOCKET(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+ ICMP6_FILTER_SETPASSALL(&i6f);
+ SAFE_SETSOCKOPT(sall, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f, sizeof(i6f));
- rv = -1;
+ sf = SAFE_SOCKET(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+}
- switch (ftab[i].ft_test) {
- case T_SETPASS:
- ICMP6_FILTER_SETBLOCKALL(&i6f);
- ICMP6_FILTER_SETPASS(ftab[i].ft_flttype, &i6f);
- break;
- case T_SETPASSALL:
- ICMP6_FILTER_SETPASSALL(&i6f);
- break;
- case T_SETBLOCK:
- ICMP6_FILTER_SETPASSALL(&i6f);
- ICMP6_FILTER_SETBLOCK(ftab[i].ft_flttype, &i6f);
- break;
- case T_SETBLOCKALL:
- ICMP6_FILTER_SETBLOCKALL(&i6f);
- break;
- case T_WILLBLOCK:
- ICMP6_FILTER_SETPASSALL(&i6f);
- ICMP6_FILTER_SETBLOCK(ftab[i].ft_flttype, &i6f);
- rv = ICMP6_FILTER_WILLBLOCK(ftab[i].ft_sndtype, &i6f);
- break;
- case T_WILLPASS:
- ICMP6_FILTER_SETBLOCKALL(&i6f);
- ICMP6_FILTER_SETPASS(ftab[i].ft_flttype, &i6f);
- rv = ICMP6_FILTER_WILLPASS(ftab[i].ft_sndtype, &i6f);
- break;
- default:
- tst_resm(TBROK, "%s: unknown test type %d",
- ftab[i].ft_tname, ftab[i].ft_test);
- continue;
- }
- if (ftab[i].ft_test != T_WILLBLOCK &&
- ftab[i].ft_test != T_WILLPASS) {
- if (setsockopt(sf, IPPROTO_ICMPV6, ICMP6_FILTER, &i6f,
- sizeof(i6f)) < 0) {
- tst_resm(TFAIL | TERRNO,
- "setsockopt ICMP6_FILTER");
- continue;
- }
- if (ic6_send1(ftab[i].ft_tname, ftab[i].ft_sndtype))
- continue;
- rv = ic6_recv1(ftab[i].ft_tname, sall, sf);
- } else {
- rv = -1;
- }
+static void cleanup(void)
+{
+ if (sall > -1)
+ SAFE_CLOSE(sall);
- if (rv < 0)
- continue;
- if (rv != ftab[i].ft_expected)
- tst_resm(TFAIL, "%s: rv %d != expected %d",
- ftab[i].ft_tname, rv, ftab[i].ft_expected);
- else
- tst_resm(TPASS, "%s", ftab[i].ft_tname);
- }
+ if (sf > -1)
+ SAFE_CLOSE(sf);
}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = verify_icmp6_filter,
+ .tcnt = ARRAY_SIZE(tcases)
+};
diff --git a/testcases/network/lib6/asapi_03.c b/testcases/network/lib6/asapi_03.c
index 2124ba7d9..87d050add 100644
--- a/testcases/network/lib6/asapi_03.c
+++ b/testcases/network/lib6/asapi_03.c
@@ -43,7 +43,7 @@
#include "test.h"
#include "safe_macros.h"
-char *TCID = "asapi_06";
+char *TCID = "asapi_03";
int TST_TOTAL = 1;
diff --git a/testcases/network/netstress/netstress.c b/testcases/network/netstress/netstress.c
index 6a888f2ee..fb6281cd0 100644
--- a/testcases/network/netstress/netstress.c
+++ b/testcases/network/netstress/netstress.c
@@ -384,6 +384,7 @@ void *client_fn(void *id)
inf.raddr_len = sizeof(inf.raddr);
inf.etime_cnt = 0;
+ inf.eshutdown_cnt = 0;
inf.timeout = wait_timeout;
inf.pmtu_err_cnt = 0;
diff --git a/testcases/network/nfs/nfs_stress/Makefile b/testcases/network/nfs/nfs_stress/Makefile
index 8cd095867..5b396dede 100644
--- a/testcases/network/nfs/nfs_stress/Makefile
+++ b/testcases/network/nfs/nfs_stress/Makefile
@@ -9,13 +9,6 @@ include $(top_srcdir)/include/mk/testcases.mk
nfs04_create_file: CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
nfs05_make_tree: LDLIBS += -lpthread
-INSTALL_TARGETS := nfs_lib.sh \
- nfs01.sh \
- nfs02.sh \
- nfs03.sh \
- nfs04.sh \
- nfs05.sh \
- nfs06.sh \
- nfs07.sh
+INSTALL_TARGETS := *.sh
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/network/nfs/nfs_stress/nfs03.sh b/testcases/network/nfs/nfs_stress/nfs03.sh
index e5f4de67c..e9ef5fb78 100755
--- a/testcases/network/nfs/nfs_stress/nfs03.sh
+++ b/testcases/network/nfs/nfs_stress/nfs03.sh
@@ -66,11 +66,13 @@ do_test()
cd ../dir1
wait $pid1
rm_files &
+ pid3=$!
tst_res TINFO "cd dir2 & removing files"
cd ../dir2
wait $pid2
rm_files
+ wait $pid3
tst_res TPASS "test done"
}
diff --git a/testcases/network/nfs/nfs_stress/nfs05.sh b/testcases/network/nfs/nfs_stress/nfs05.sh
index c18ef1ab4..760b585e4 100755
--- a/testcases/network/nfs/nfs_stress/nfs05.sh
+++ b/testcases/network/nfs/nfs_stress/nfs05.sh
@@ -8,9 +8,9 @@
#
# Created by: Robbie Williamson (robbiew@us.ibm.com)
-DIR_NUM=${DIR_NUM:-"10"}
-FILE_NUM=${FILE_NUM:-"30"}
-THREAD_NUM=${THREAD_NUM:-"8"}
+DIR_NUM=${DIR_NUM:-"5"}
+FILE_NUM=${FILE_NUM:-"20"}
+THREAD_NUM=${THREAD_NUM:-"5"}
TST_NEEDS_CMDS="make gcc"
TST_TESTFUNC="do_test"
diff --git a/testcases/network/nfs/nfs_stress/nfs06.sh b/testcases/network/nfs/nfs_stress/nfs06.sh
index d51f7dc82..560df05b1 100755
--- a/testcases/network/nfs/nfs_stress/nfs06.sh
+++ b/testcases/network/nfs/nfs_stress/nfs06.sh
@@ -11,7 +11,8 @@
TST_TESTFUNC="do_test"
TST_CLEANUP="do_cleanup"
-THREAD_NUM=${THREAD_NUM:-"2"}
+THREAD_NUM="${THREAD_NUM:-2}"
+OPERATION_NUM="${OPERATION_NUM:-1000}"
do_cleanup()
{
@@ -26,7 +27,7 @@ do_test()
local n=0
local pids
for i in $VERSION; do
- fsstress -l 1 -d $TST_TMPDIR/$i/$n -n 1000 -p $THREAD_NUM -r -c > /dev/null &
+ fsstress -l 1 -d $TST_TMPDIR/$i/$n -n $OPERATION_NUM -p $THREAD_NUM -r -c > /dev/null &
pids="$pids $!"
n=$(( n + 1 ))
done
diff --git a/testcases/network/nfs/nfs_stress/nfs08.sh b/testcases/network/nfs/nfs_stress/nfs08.sh
new file mode 100755
index 000000000..759b4e418
--- /dev/null
+++ b/testcases/network/nfs/nfs_stress/nfs08.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+# Test for broken NFS cache invalidation for directories.
+# Kernel patch broke cache invalidation, which caused the second 'ls'
+# not shown '2'.
+# https://lore.kernel.org/linux-nfs/167649314509.15170.15885497881041431304@noble.neil.brown.name/
+# Based on reproducer from Neil Brown <neilb@suse.de>
+
+TST_TESTFUNC="do_test"
+
+do_test()
+{
+ tst_res TINFO "testing NFS cache invalidation for directories"
+
+ touch 1
+ EXPECT_PASS 'ls | grep 1'
+ touch 2
+ EXPECT_PASS 'ls | grep 2'
+}
+
+. nfs_lib.sh
+tst_run
diff --git a/testcases/network/nfs/nfs_stress/nfs_lib.sh b/testcases/network/nfs/nfs_stress/nfs_lib.sh
index af7d46a21..a996f7cc8 100644
--- a/testcases/network/nfs/nfs_stress/nfs_lib.sh
+++ b/testcases/network/nfs/nfs_stress/nfs_lib.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (c) Linux Test Project, 2016-2022
+# Copyright (c) Linux Test Project, 2016-2023
# Copyright (c) 2015-2018 Oracle and/or its affiliates. All Rights Reserved.
# Copyright (c) International Business Machines Corp., 2001
@@ -28,7 +28,10 @@ NFS_PARSE_ARGS_CALLER="$TST_PARSE_ARGS"
TST_OPTS="v:t:$TST_OPTS"
TST_PARSE_ARGS=nfs_parse_args
TST_USAGE=nfs_usage
-TST_NEEDS_TMPDIR=1
+TST_ALL_FILESYSTEMS=1
+TST_SKIP_FILESYSTEMS="exfat,ext2,ext3,fuse,ntfs,vfat,tmpfs"
+TST_MOUNT_DEVICE=1
+TST_FORMAT_DEVICE=1
TST_NEEDS_ROOT=1
TST_NEEDS_CMDS="$TST_NEEDS_CMDS mount exportfs mount.nfs"
TST_SETUP="${TST_SETUP:-nfs_setup}"
@@ -53,6 +56,24 @@ get_socket_type()
done
}
+# directory mounted by NFS client
+get_local_dir()
+{
+ local v="$1"
+ local n="$2"
+
+ echo "$TST_TMPDIR/$v/$n"
+}
+
+# directory on NFS server
+get_remote_dir()
+{
+ local v="$1"
+ local n="$2"
+
+ echo "$TST_MNTPOINT/$v/$n"
+}
+
nfs_get_remote_path()
{
local v
@@ -63,7 +84,7 @@ nfs_get_remote_path()
done
v=${1:-$v}
- echo "$TST_TMPDIR/$v/$type"
+ echo "$(get_remote_dir $v $type)"
}
nfs_server_udp_enabled()
@@ -78,8 +99,8 @@ nfs_server_udp_enabled()
nfs_setup_server()
{
-
- local fsid="$1"
+ local remote_dir="$1"
+ local fsid="$2"
local export_cmd="exportfs -i -o fsid=$fsid,no_root_squash,rw *:$remote_dir"
[ -z "$fsid" ] && tst_brk TBROK "empty fsid"
@@ -97,10 +118,14 @@ nfs_setup_server()
nfs_mount()
{
- local opts="$1"
+ local local_dir="$1"
+ local remote_dir="$2"
+ local opts="$3"
local host_type=rhost
local mount_dir
+ mkdir -p "$local_dir"
+
tst_net_use_netns && host_type=
if [ $TST_IPV6 ]; then
@@ -131,6 +156,8 @@ nfs_mount()
tst_brk TBROK "mount command failed"
fi
+
+ cd "$local_dir"
}
nfs_setup()
@@ -162,20 +189,14 @@ nfs_setup()
tst_brk TCONF "UDP support disabled on NFS server"
fi
- local_dir="$TST_TMPDIR/$i/$n"
- remote_dir="$TST_TMPDIR/$i/$type"
- mkdir -p $local_dir
-
- nfs_setup_server $(($$ + n))
-
- nfs_mount "-o proto=$type,vers=$i"
+ remote_dir="$(get_remote_dir $i $type)"
+ nfs_setup_server "$remote_dir" "$(($$ + n))"
+ local_dir="$(get_local_dir $i $n)"
+ tst_res TINFO "Mounting $local_dir"
+ nfs_mount "$local_dir" "$remote_dir" "-o proto=$type,vers=$i"
n=$(( n + 1 ))
done
-
- if [ "$n" -eq 1 ]; then
- cd ${VERSION}/0
- fi
}
nfs_cleanup()
@@ -190,17 +211,32 @@ nfs_cleanup()
local n=0
for i in $VERSION; do
- local_dir="$TST_TMPDIR/$i/$n"
- grep -q "$local_dir" /proc/mounts && umount $local_dir
+ local_dir="$(get_local_dir $i $n)"
+ if grep -q "$local_dir" /proc/mounts; then
+ tst_res TINFO "Unmounting $local_dir"
+ umount $local_dir
+ fi
n=$(( n + 1 ))
done
+ sleep 2
n=0
for i in $VERSION; do
type=$(get_socket_type $n)
- remote_dir="$TST_TMPDIR/$i/$type"
- tst_rhost_run -c "test -d $remote_dir && exportfs -u *:$remote_dir"
- tst_rhost_run -c "test -d $remote_dir && rm -rf $remote_dir"
+ remote_dir="$(get_remote_dir $i $type)"
+
+ if tst_net_use_netns; then
+ if test -d $remote_dir; then
+ exportfs -u *:$remote_dir
+ sleep 1
+ rm -rf $remote_dir
+ fi
+ else
+ tst_rhost_run -c "test -d $remote_dir && exportfs -u *:$remote_dir"
+ sleep 1
+ tst_rhost_run -c "test -d $remote_dir && rm -rf $remote_dir"
+ fi
+
n=$(( n + 1 ))
done
}
diff --git a/testcases/network/nfs/nfslock01/nfs_flock.c b/testcases/network/nfs/nfslock01/nfs_flock.c
index a7673c751..02f105b22 100644
--- a/testcases/network/nfs/nfslock01/nfs_flock.c
+++ b/testcases/network/nfs/nfslock01/nfs_flock.c
@@ -1,7 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
+ * Copyright (c) Linux Test Project, 2001-2023
+ * Copyright (c) International Business Machines Corp., 2001
+ */
+
+/*\
+ * [Description]
+ *
* Program for testing file locking. The original data file consists of
* characters from 'A' to 'Z'. The data file after running this program
* would consist of lines with 1's in even lines and 0's in odd lines.
+ *
+ * Used in nfslock01.sh.
*/
#include "nfs_flock.h"
@@ -10,69 +20,91 @@
#include <stdlib.h>
#include <unistd.h>
-#define BYTES 64
-#define LINES 16384
-
int main(int argc, char **argv)
{
- int i, fd, mac;
+ int i, fd, mac, nchars, nlines;
int offset = 0;
char buf[BUFSIZ];
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <mac num> <file name>\n", argv[0]);
+ if (argc != 5) {
+ fprintf(stderr, "Usage: %s <mac num> <file name> <nchars> <nlines>\n",
+ argv[0]);
exit(2);
}
- if ((fd = open(argv[2], O_RDWR)) < 0) {
+ fd = open(argv[2], O_RDWR);
+ if (fd < 0) {
perror("opening a file");
exit(1);
}
mac = atoi(argv[1]);
+ nchars = atoi(argv[3]);
+ nlines = atoi(argv[4]);
+
+ if (nchars > BUFSIZ) {
+ fprintf(stderr, "Exceeded the maximum limit of the buffer (%d)\n", BUFSIZ);
+ exit(3);
+ }
+
+ if (nchars < 1) {
+ fprintf(stderr, "<char/line> must be > 0\n");
+ exit(3);
+ }
+
+ if (nlines < 1) {
+ fprintf(stderr, "<lines> must be > 0\n");
+ exit(3);
+ }
/*
* Replace a line of characters by 1's if it is process one
- * else with 0's. Number of charcters in any line are BYTES-1,
+ * else with 0's. Number of charcters in any line are nchars-1,
* the last character being a newline character.
*/
- for (i = 0; i < BYTES - 1; i++) {
+ for (i = 0; i < nchars - 1; i++) {
if (mac == 1)
buf[i] = '1';
else
buf[i] = '0';
}
- buf[BYTES - 1] = '\n';
+ buf[nchars - 1] = '\n';
- for (i = 0; i < LINES; i++) {
+ for (i = 0; i < nlines; i++) {
if (mac == 1) { /* Set the offset to even lines */
if ((i % 2) == 0) {
if (i == 0)
offset = 0;
else
- offset += 2 * BYTES;
+ offset += 2 * nchars;
} else
continue;
} else { /* Set the offset to odd lines */
if ((i % 2) == 1) {
if (i == 1)
- offset = BYTES;
+ offset = nchars;
else
- offset += 2 * BYTES;
+ offset += 2 * nchars;
} else
continue;
}
- if (writeb_lock(fd, offset, SEEK_SET, BYTES) < 0)
- printf("failed in writeb_lock, Errno = %d", errno);
+ if (writeb_lock(fd, offset, SEEK_SET, nchars) < 0) {
+ fprintf(stderr, "failed in writeb_lock, errno = %d\n", errno);
+ exit(1);
+ }
lseek(fd, offset, SEEK_SET);
- /* write to the test file */
- write(fd, buf, BYTES);
+ if (write(fd, buf, nchars) < 0) {
+ fprintf(stderr, "failed to write buffer to test file, errno = %d\n", errno);
+ exit(1);
+ }
- if (unb_lock(fd, offset, SEEK_SET, BYTES) < 0)
- printf("failed in unb_lock, Errno = %d", errno);
+ if (unb_lock(fd, offset, SEEK_SET, nchars) < 0) {
+ fprintf(stderr, "failed in unb_lock, errno = %d\n", errno);
+ exit(1);
+ }
}
exit(0);
}
diff --git a/testcases/network/nfs/nfslock01/nfs_flock.h b/testcases/network/nfs/nfslock01/nfs_flock.h
index 09e3845f4..fba4a7f02 100644
--- a/testcases/network/nfs/nfslock01/nfs_flock.h
+++ b/testcases/network/nfs/nfslock01/nfs_flock.h
@@ -1,3 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Linux Test Project, 2001-2009
+ * Copyright (c) International Business Machines Corp., 2001
+ */
+
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
diff --git a/testcases/network/nfs/nfslock01/nfs_flock_dgen.c b/testcases/network/nfs/nfslock01/nfs_flock_dgen.c
index 2b33ca974..6ecdcdc4f 100644
--- a/testcases/network/nfs/nfslock01/nfs_flock_dgen.c
+++ b/testcases/network/nfs/nfslock01/nfs_flock_dgen.c
@@ -1,5 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * This program generates data for testing file locking
+ * Copyright (c) Linux Test Project, 2001-2023
+ * Copyright (c) International Business Machines Corp., 2001
+ */
+
+/*\
+ * [Description]
+ *
+ * Tool to generate data for testing file locking.
+ * Used in nfslock01.sh.
*/
#include <stdio.h>
@@ -13,32 +22,39 @@ int main(int argc, char **argv)
FILE *fp;
if (argc != 5) {
- printf
- ("usage: <nfs_flock_dgen> <file> <char/line> <lines> <ctype>\n");
+ fprintf(stderr, "usage: <nfs_flock_dgen> <file> <char/line> <lines> <ctype>\n");
exit(2);
}
fp = fopen(argv[1], "w");
nchars = atoi(argv[2]);
+ nlines = atoi(argv[3]);
+ ctype = atoi(argv[4]);
+
if (nchars > BUFSIZ) {
- printf("Exceeded the maximum limit of the buffer (%d)\n",
- BUFSIZ);
+ fprintf(stderr, "Exceeded the maximum limit of the buffer (%d)\n", BUFSIZ);
+ exit(3);
+ }
+
+ if (nchars < 1) {
+ fprintf(stderr, "<char/line> must be > 0\n");
+ exit(3);
+ }
+
+ if (nlines < 1) {
+ fprintf(stderr, "<lines> must be > 0\n");
exit(3);
}
- nlines = atoi(argv[3]);
- ctype = atoi(argv[4]);
k = 0;
for (i = 1; i <= nlines; i++) {
-
if (ctype)
c = ((i % 2) ? '1' : '0');
else
c = 'A' + k;
- for (j = 0; j < nchars; j++)
-
+ for (j = 0; j < nchars - 1; j++)
buf[j] = c;
fprintf(fp, "%s\n", buf);
@@ -53,5 +69,6 @@ int main(int argc, char **argv)
}
fclose(fp);
- return (0);
+
+ return 0;
}
diff --git a/testcases/network/nfs/nfslock01/nfs_flock_func.c b/testcases/network/nfs/nfslock01/nfs_flock_func.c
index 811136188..aee66f40b 100644
--- a/testcases/network/nfs/nfslock01/nfs_flock_func.c
+++ b/testcases/network/nfs/nfslock01/nfs_flock_func.c
@@ -1,3 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Linux Test Project, 2001-2012
+ * Copyright (c) International Business Machines Corp., 2001
+ */
+
#include <stdlib.h>
#include <unistd.h>
diff --git a/testcases/network/nfs/nfslock01/nfslock01.sh b/testcases/network/nfs/nfslock01/nfslock01.sh
index fbcc3c00f..01d59ce85 100755
--- a/testcases/network/nfs/nfslock01/nfslock01.sh
+++ b/testcases/network/nfs/nfslock01/nfslock01.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (c) Linux Test Project, 2002-2022
+# Copyright (c) Linux Test Project, 2002-2023
# Copyright (c) 2016-2018 Oracle and/or its affiliates. All Rights Reserved.
# Copyright (c) International Business Machines Corp., 2001
#
@@ -13,19 +13,42 @@
TST_SETUP="do_setup"
TST_TESTFUNC="do_test"
+NCHARS=${NCHARS:-64}
+NLINES=${NLINES:-16384}
+
+generate_file()
+{
+ local file="$1"
+ local nchars="$2"
+ local nlines="$3"
+ local val="$4"
+ local exp_size="$((nchars*nlines))"
+ local size
+
+ ROD nfs_flock_dgen $file $nchars $nlines $val
+
+ size="$(wc -c $file | awk '{print $1}')"
+ if [ $size -ne $exp_size ]; then
+ tst_brk TBROK "could not create '$file' (size: $size, expected: $exp_size)"
+ fi
+}
+
do_setup()
{
- nfs_setup
+ if ! tst_is_int $NCHARS || [ $NCHARS -lt 1 ]; then
+ tst_res TBROK "NCHARS must be > 0"
+ fi
- tst_res TINFO "creating test files"
- ROD nfs_flock_dgen flock_data 63 16384 0
- ROD nfs_flock_dgen flock_odata 63 16384 1
+ if ! tst_is_int $NLINES || [ $NLINES -lt 1 ]; then
+ tst_res TBROK "NLINES must be > 0"
+ fi
+
+ nfs_setup
- [ "$(wc -c flock_data | awk '{print $1}')" -ne 1048576 ] && \
- tst_brk TBROK "could not create 'flock_data'"
+ tst_res TINFO "creating test files (chars: $NCHARS, lines: $NLINES)"
- [ "$(wc -c flock_odata | awk '{print $1}')" -ne 1048576 ] && \
- tst_brk TBROK "could not create 'flock_odata'"
+ generate_file flock_data $NCHARS $NLINES 0
+ generate_file flock_odata $NCHARS $NLINES 1
}
do_test()
@@ -36,9 +59,9 @@ do_test()
tst_res TINFO "locking 'flock_idata' file and writing data"
- nfs_flock 0 flock_idata &
+ nfs_flock 0 flock_idata $NCHARS $NLINES &
local pids=$!
- nfs_flock 1 flock_idata &
+ nfs_flock 1 flock_idata $NCHARS $NLINES &
pids="$pids $!"
tst_res TINFO "waiting for pids: $pids"
diff --git a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast.c b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast.c
index 5f024f113..80d5f045a 100644
--- a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast.c
+++ b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast.c
@@ -59,7 +59,8 @@ int main(int argn, char *argc[])
//Call broadcast routine
cs = clnt_broadcast(progNum, VERSNUM, PROCNUM,
(xdrproc_t) xdr_int, (char *)&varSnd,
- (xdrproc_t) xdr_int, (char *)&varRec, eachResult);
+ (xdrproc_t) xdr_int, (char *)&varRec,
+ (resultproc_t) eachResult);
test_status = (cs == RPC_SUCCESS) ? 0 : 1;
diff --git a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_complex.c b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_complex.c
index c6e55cd81..e1bb8fcc5 100644
--- a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_complex.c
+++ b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_complex.c
@@ -78,7 +78,8 @@ int main(int argn, char *argc[])
//Call broadcast routine
cs = clnt_broadcast(progNum, VERSNUM, PROCNUM,
(xdrproc_t) xdr_int, (char *)&varSnd,
- (xdrproc_t) xdr_int, (char *)&varRec, eachResult);
+ (xdrproc_t) xdr_int, (char *)&varRec,
+ (resultproc_t) eachResult);
if (currentAnswer == maxAnswer)
test_status = 0;
diff --git a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_dataint.c b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_dataint.c
index fdf1e31a2..e1f7bcb6a 100644
--- a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_dataint.c
+++ b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_dataint.c
@@ -72,7 +72,8 @@ int main(int argn, char *argc[])
clnt_broadcast(progNum, VERSNUM, INTPROCNUM,
(xdrproc_t) xdr_int, (char *)&intSnd,
- (xdrproc_t) xdr_int, (char *)&intRec, eachResult);
+ (xdrproc_t) xdr_int, (char *)&intRec,
+ (resultproc_t) eachResult);
if (intSnd != intRec)
test_status = 1;
@@ -84,7 +85,8 @@ int main(int argn, char *argc[])
clnt_broadcast(progNum, VERSNUM, INTPROCNUM,
(xdrproc_t) xdr_int, (char *)&intSnd,
- (xdrproc_t) xdr_int, (char *)&intRec, eachResult);
+ (xdrproc_t) xdr_int, (char *)&intRec,
+ (resultproc_t) eachResult);
if (intSnd != intRec)
test_status = 1;
@@ -96,7 +98,8 @@ int main(int argn, char *argc[])
clnt_broadcast(progNum, VERSNUM, LNGPROCNUM,
(xdrproc_t) xdr_long, (char *)&lngSnd,
- (xdrproc_t) xdr_long, (char *)&lngRec, eachResult);
+ (xdrproc_t) xdr_long, (char *)&lngRec,
+ (resultproc_t) eachResult);
if (lngSnd != lngRec)
test_status = 1;
@@ -108,7 +111,8 @@ int main(int argn, char *argc[])
clnt_broadcast(progNum, VERSNUM, LNGPROCNUM,
(xdrproc_t) xdr_double, (char *)&dblSnd,
- (xdrproc_t) xdr_double, (char *)&dblRec, eachResult);
+ (xdrproc_t) xdr_double, (char *)&dblRec,
+ (resultproc_t) eachResult);
if (dblSnd != dblRec)
test_status = 1;
@@ -121,7 +125,8 @@ int main(int argn, char *argc[])
clnt_broadcast(progNum, VERSNUM, LNGPROCNUM,
(xdrproc_t) xdr_wrapstring, (char *)&strSnd,
- (xdrproc_t) xdr_wrapstring, (char *)&strRec, eachResult);
+ (xdrproc_t) xdr_wrapstring, (char *)&strRec,
+ (resultproc_t) eachResult);
if (strcmp(strSnd, strRec))
test_status = 1;
diff --git a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_performance.c b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_performance.c
index 11ba64fab..d733e72ef 100644
--- a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_performance.c
+++ b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_performance.c
@@ -114,7 +114,7 @@ int main(int argn, char *argc[])
cs = clnt_broadcast(progNum, VERSNUM, PROCNUM,
(xdrproc_t) xdr_int, (char *)&varSnd,
(xdrproc_t) xdr_int, (char *)&varRec,
- eachResult);
+ (resultproc_t) eachResult);
if (cs != RPC_SUCCESS)
clnt_perrno(cs);
diff --git a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_scalability.c b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_scalability.c
index 57ea25349..4455c1173 100644
--- a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_scalability.c
+++ b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_scalability.c
@@ -114,7 +114,7 @@ int main(int argn, char *argc[])
cs = clnt_broadcast(progNum, VERSNUM, PROCNUM,
(xdrproc_t) xdr_int, (char *)&varSnd,
(xdrproc_t) xdr_int, (char *)&varRec,
- eachResult);
+ (resultproc_t) eachResult);
if (cs != RPC_SUCCESS)
clnt_perrno(cs);
diff --git a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_stress.c b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_stress.c
index d5d7d85d1..933305482 100644
--- a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_stress.c
+++ b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_broadc_clnt_broadcast/rpc_clnt_broadcast_stress.c
@@ -65,7 +65,7 @@ int main(int argn, char *argc[])
cs = clnt_broadcast(progNum, VERSNUM, PROCNUM,
(xdrproc_t) xdr_int, (char *)&varSnd,
(xdrproc_t) xdr_int, (char *)&varRec,
- eachResult);
+ (resultproc_t) eachResult);
if (cs == RPC_SUCCESS)
nbOk++;
}
diff --git a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_regunreg_registerrpc/rpc_registerrpc.c b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_regunreg_registerrpc/rpc_registerrpc.c
index 3becf4600..c6fb3e0f6 100644
--- a/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_regunreg_registerrpc/rpc_registerrpc.c
+++ b/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_regunreg_registerrpc/rpc_registerrpc.c
@@ -67,9 +67,8 @@ int main(int argn, char *argc[])
svcr = svcudp_create(RPC_ANYSOCK);
//call routine
- rslt =
- registerrpc(progNum, VERSNUM, PROCNUM, simplePing, xdr_int,
- xdr_int);
+ rslt = registerrpc(progNum, VERSNUM, PROCNUM, simplePing,
+ (xdrproc_t) xdr_int, (xdrproc_t) xdr_int);
if (run_mode) {
printf("SVC : %p\n", svcr);
diff --git a/testcases/network/sctp/sctp_big_chunk.c b/testcases/network/sctp/sctp_big_chunk.c
index a6a326ea2..467486846 100644
--- a/testcases/network/sctp/sctp_big_chunk.c
+++ b/testcases/network/sctp/sctp_big_chunk.c
@@ -1,9 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-/* Copyright (c) 2018 Oracle and/or its affiliates. All Rights Reserved.
+/*
+ * Copyright (c) 2018 Oracle and/or its affiliates. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2019-2023
+ */
+
+/*\
+ * [Description]
*
- * Regression test-case for the crash caused by over-sized SCTP chunk,
+ * Regression test for the crash caused by over-sized SCTP chunk,
* fixed by upstream commit 07f2c7ab6f8d ("sctp: verify size of a new
- * chunk in _sctp_make_chunk()")
+ * chunk in _sctp_make_chunk()").
*/
#include <stdlib.h>
@@ -34,6 +40,26 @@ static int addr_num = 3273;
static void setup_server(void)
{
+ const char hmac_algo_path[] = "/proc/sys/net/sctp/cookie_hmac_alg";
+ char hmac_algo[CHAR_MAX];
+ int hmac_algo_changed = 0;
+ int fd;
+
+ /* Disable md5 if fips is enabled. Set it to none */
+ if (tst_fips_enabled()) {
+ /* Load sctp module */
+ if (access(hmac_algo_path, F_OK) < 0) {
+ fd = SAFE_SOCKET(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+ SAFE_CLOSE(fd);
+ }
+
+ if (!access(hmac_algo_path, F_OK)) {
+ SAFE_FILE_SCANF(hmac_algo_path, "%s", hmac_algo);
+ SAFE_FILE_PRINTF(hmac_algo_path, "%s", "none");
+ hmac_algo_changed = 1;
+ }
+ }
+
loc.sin6_family = AF_INET6;
loc.sin6_addr = in6addr_loopback;
@@ -46,6 +72,9 @@ static void setup_server(void)
SAFE_LISTEN(sfd, 1);
srand(port);
+
+ if (hmac_algo_changed)
+ SAFE_FILE_PRINTF(hmac_algo_path, "%s", hmac_algo);
}
static void update_packet_field(size_t *off, void *buf, size_t buf_len)
diff --git a/testcases/network/sockets/vsock01.c b/testcases/network/sockets/vsock01.c
index 1e688df19..7be71a83b 100644
--- a/testcases/network/sockets/vsock01.c
+++ b/testcases/network/sockets/vsock01.c
@@ -8,10 +8,11 @@
*
* Reproducer of CVE-2021-26708
*
- * Based on POC https://github.com/jordan9001/vsock_poc
+ * Based on POC https://github.com/jordan9001/vsock_poc.
* Fuzzy Sync has been substituted for userfaultfd.
*
* Fixed by: c518adafa39f ("vsock: fix the race conditions in multi-transport support")
+ *
* Fixes: c0cfa2d8a788fcf4 ("vsock: add multi-transports support")
*
* Note that in many testing environments this will reproduce the race
diff --git a/testcases/network/stress/udp/multi-diffip/udp4-multi-diffip01 b/testcases/network/stress/udp/multi-diffip/udp4-multi-diffip01
index 92af9e438..c0d50efaf 100644
--- a/testcases/network/stress/udp/multi-diffip/udp4-multi-diffip01
+++ b/testcases/network/stress/udp/multi-diffip/udp4-multi-diffip01
@@ -230,7 +230,7 @@ while [ $ipaddr_pair_num -lt $IP_TOTAL_FOR_TCPIP ]; do
# Set IPv6 addresses to the interfaces
ip addr add ${lhost_addr}/${network_mask} dev $lhost_ifname
- if [ $ret -eq 2 ]; then
+ if [ $? -eq 2 ]; then
ip addr del ${lhost_addr}/${network_mask} dev $lhost_ifname 2>&1
ip addr add ${lhost_addr}/${network_mask} dev $lhost_ifname
fi
diff --git a/testcases/network/tcp_cmds/ipneigh/ipneigh01.sh b/testcases/network/tcp_cmds/ipneigh/ipneigh01.sh
index 644a1fb8d..e67ff5cc8 100755
--- a/testcases/network/tcp_cmds/ipneigh/ipneigh01.sh
+++ b/testcases/network/tcp_cmds/ipneigh/ipneigh01.sh
@@ -25,7 +25,7 @@ do_setup()
if [ -n "$TST_IPV6" ]; then
tst_brk TCONF "'arp' doesn't support IPv6"
fi
- SHOW_CMD="arp -a"
+ SHOW_CMD="arp -an"
DEL_CMD="ROD arp -d $(tst_ipaddr rhost) -i $(tst_iface)"
;;
*)
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/aio_read/8-1.c b/testcases/open_posix_testsuite/conformance/interfaces/aio_read/8-1.c
index 8a6c024a9..e0fecd805 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/aio_read/8-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/aio_read/8-1.c
@@ -10,7 +10,7 @@
* assertion:
*
* The aio_read() function shall return the value -1 and set errno to
- * indicate error if the operation is not succesfully queued.
+ * indicate error if the operation is not successfully queued.
*
* method:
*
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/aio_read/assertions.xml b/testcases/open_posix_testsuite/conformance/interfaces/aio_read/assertions.xml
index e23c6bcf6..ae2062221 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/aio_read/assertions.xml
+++ b/testcases/open_posix_testsuite/conformance/interfaces/aio_read/assertions.xml
@@ -28,7 +28,7 @@
</assertion>
<assertion id="8" tag="ref:XSH6TC2:4155:4155">
The aio_read() function shall return the value -1 and set errno to
- indicate error if the operation is not succesfully queued.
+ indicate error if the operation is not successfully queued.
</assertion>
<assertion id="9" tag="ref:XSH6TC2:4158:4159">
aio_read() shall fail with [EAGAIN] if:
@@ -46,16 +46,16 @@
value, or aio_nbytes is an invalid value.
</assertion>
<assertion id="12" tag="ref:XSH6TC2:4174:4174">
- The error status of a succesfully queued operation shall be:
+ The error status of a successfully queued operation shall be:
[EBADF] if the aio_fildes argument is not a valid file descriptor open for
reading.
</assertion>
<assertion id="13" tag="ref:XSH6TC2:4375:4376">
- The error status of a succesfully queued operation shall be:
+ The error status of a successfully queued operation shall be:
[ECANCELED] if The requested I/O was canceled before the I/O completed.
</assertion>
<assertion id="14" tag="ref:XSH6TC2:4177:4177">
- The error status of a succesfully queued operation shall be:
+ The error status of a successfully queued operation shall be:
[EINVAL] if aio_offset would be invalid, or aio_reqprio is not a valid
value, or aio_nbytes is an invalid value.
</assertion>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/aio_write/6-1.c b/testcases/open_posix_testsuite/conformance/interfaces/aio_write/6-1.c
index 2948552c4..60428ce27 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/aio_write/6-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/aio_write/6-1.c
@@ -10,7 +10,7 @@
* assertion:
*
* The aio_write() function shall return the value -1 and set errno to
- indicate error if the operation is not succesfully queued.
+ indicate error if the operation is not successfully queued.
*
* method:
*
@@ -18,7 +18,6 @@
* aiocb with invalid aio_reqprio
* - call aio_write
* - check aio_write return value
- *
*/
#include <stdio.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/aio_write/assertions.xml b/testcases/open_posix_testsuite/conformance/interfaces/aio_write/assertions.xml
index 86694021f..e00774c61 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/aio_write/assertions.xml
+++ b/testcases/open_posix_testsuite/conformance/interfaces/aio_write/assertions.xml
@@ -21,7 +21,7 @@
</assertion>
<assertion id="6" tag="ref:XSH6TC2:4348:4349">
The aio_write() function shall return the value -1 and set errno to
- indicate error if the operation is not succesfully queued.
+ indicate error if the operation is not successfully queued.
</assertion>
<assertion id="7" tag="ref:XSH6TC2:4352:4353">
aio_write() shall fail with [EAGAIN] if:
@@ -38,17 +38,17 @@
aio_nbytes is an invalid value.
</assertion>
<assertion id="10" tag="ref:XSH6TC2:4369:4369">
- The error status of a succesfully queued operation shall be:
+ The error status of a successfully queued operation shall be:
[EBADF] if the aio_fildes argument is not a valid file descriptor open for
writing.
</assertion>
<assertion id="11" tag="ref:XSH6TC2:4370:4370">
- The error status of a succesfully queued operation shall be:
+ The error status of a successfully queued operation shall be:
[EINVAL] if aio_offset would be invalid, or aio_reqprio is not a valid
value, or aio_nbytes is an invalid value.
</assertion>
<assertion id="12" tag="ref:XSH6TC2:4371:4372">
- The error status of a succesfully queued operation shall be:
+ The error status of a successfully queued operation shall be:
[ECANCELED] The requested I/O was canceled before the I/O completed.
</assertion>
<assertion id="13" tag="ref:XSH6TC2:4374:4376">
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/fork/assertions.xml b/testcases/open_posix_testsuite/conformance/interfaces/fork/assertions.xml
index 48abbfbe8..64793fc3f 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/fork/assertions.xml
+++ b/testcases/open_posix_testsuite/conformance/interfaces/fork/assertions.xml
@@ -83,7 +83,7 @@
</assertion>
<assertion id="23" tag="ref:XSH6TC2:13060:13062">
fork() returns 0 to the child and the child PID to the parent process when
- succesful.
+ successful.
</assertion>
<assertion id="24" tag="ref:XSH6TC2:13063:13069">
fork() returns -1, errno is set to EAGAIN, and no child process
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/13-1.c b/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/13-1.c
index 33915a440..48754f815 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/13-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/13-1.c
@@ -10,7 +10,7 @@
* assertion:
*
* if mode is LIO_WAIT, lio_listio() shall return the value -1 and set
- * errno to indicate error if the operation is not succesfully queued.
+ * errno to indicate error if the operation is not successfully queued.
*
* method:
*
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/assertions.xml b/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/assertions.xml
index 8832fdd3c..5aaa78a18 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/assertions.xml
+++ b/testcases/open_posix_testsuite/conformance/interfaces/lio_listio/assertions.xml
@@ -36,7 +36,7 @@
</assertion>
<assertion id="11" tag="ref:XSH6TC2:23084:23085">
if mode is LIO_NOWAIT, lio_listio() shall return the value -1 and set
- errno to indicate error if the operation is not succesfully queued.
+ errno to indicate error if the operation is not successfully queued.
</assertion>
<assertion id="12" tag="ref:XSH6TC2:23086:23087">
if mode is LIO_WAIT, lio_listio() shall return the value zero when
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/mmap/6-5.c b/testcases/open_posix_testsuite/conformance/interfaces/mmap/6-5.c
index 33c0575c5..a27c91e46 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/mmap/6-5.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/mmap/6-5.c
@@ -71,7 +71,7 @@ int main(void)
munmap(pa, size);
close(fd);
- printf("Succesfully mapped readonly file with "
+ printf("Successfully mapped readonly file with "
"PROT_WRITE, MAP_PRIVATE\n" "Test PASSED\n");
return PTS_PASS;
}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getinheritsched/assertions.xml b/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getinheritsched/assertions.xml
index 9b2c14717..a15504bd6 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getinheritsched/assertions.xml
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getinheritsched/assertions.xml
@@ -4,7 +4,7 @@ pthread_attr_getinheritsched shall get the inheritsched attribute in the attr ar
PTHREAD_INHERIT_SCHED and PTHREAD_EXPLICIT_SCHED are valid value.
</assertion>
<assertion id="2" tag="ref:XSH6:31347:31347">
-If succesful, the pthread_attr_getinheritsched shall return zero.
+If successful, the pthread_attr_getinheritsched shall return zero.
</assertion>
<assertion id="3" tag="ref:XSH6:31348:31348">
If fail, the pthread_attr_getinheritsched shall return an error number.
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getscope/assertions.xml b/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getscope/assertions.xml
index c201c4449..f6733520c 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getscope/assertions.xml
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_attr_getscope/assertions.xml
@@ -4,7 +4,7 @@ pthread_attr_getscope shall get the inheritsched attribute in the attr argument
The contentionscope attribute may have the values PTHREAD_SCOPE_SYSTEM, signifying system scheduling contention scope, or PTHREAD_SCOPE_PROCESS, signifying process scheduling contention scope.
</assertion>
<assertion id="2" tag="ref:XSH6:31492:31492">
-If succesful, the pthread_attr_getscope shall return zero.
+If successful, the pthread_attr_getscope shall return zero.
</assertion>
<assertion id="3" tag="ref:XSH6:31493:31493">
If fail, the pthread_attr_getscope shall return an error number.
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_destroy/3-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_destroy/3-1.c
index d07a199cb..a618e98c8 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_destroy/3-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_destroy/3-1.c
@@ -6,8 +6,7 @@
* source tree.
* Test that pthread_cond_destroy()
- * Upon succesful completion, it shall return a 0
- *
+ * Upon successful completion, it shall return 0.
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_init/3-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_init/3-1.c
index f0402648f..886d0f04b 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_init/3-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_cond_init/3-1.c
@@ -6,8 +6,7 @@
* source tree.
* Test that pthread_cond_init()
- * Upon succesful completion, it shall return a 0
- *
+ * Upon successful completion, it shall return 0.
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_detach/3-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_detach/3-1.c
index 4217afa4b..80cd2ad96 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_detach/3-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_detach/3-1.c
@@ -6,14 +6,12 @@
* source tree.
* Test that pthread_detach()
- *
- * Upon succesful completion, it shall return a 0;
+ * Upon successful completion, it shall return 0.
*
* STEPS:
* 1.Create a joinable thread
* 2.Detach that thread
* 3.Check the return value
- *
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_destroy/3-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_destroy/3-1.c
index 9ce4ca105..a8b032c53 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_destroy/3-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_destroy/3-1.c
@@ -6,8 +6,7 @@
* source tree.
* Test that pthread_mutex_destroy()
- * Upon succesful completion, it shall return a 0
- *
+ * Upon successful completion, it shall return 0.
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_init/4-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_init/4-1.c
index d7b4f204e..1df6e5af2 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_init/4-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_init/4-1.c
@@ -6,8 +6,7 @@
* source tree.
* Test that pthread_mutex_init()
- * Upon succesful completion, it shall return a 0
- *
+ * Upon successful completion, it shall return 0.
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_lock/2-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_lock/2-1.c
index 7e8827c4a..a8123ba58 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_lock/2-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_lock/2-1.c
@@ -6,8 +6,7 @@
* source tree.
* Test that pthread_mutex_lock()
- * Upon succesful completion, it shall return a 0
- *
+ * Upon successful completion, it shall return 0.
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_trylock/3-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_trylock/3-1.c
index 32151322d..ea81f99ca 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_trylock/3-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_trylock/3-1.c
@@ -6,8 +6,7 @@
* source tree.
* Test that pthread_mutex_trylock()
- * Upon succesful completion, it shall return a 0
- *
+ * Upon successful completion, it shall return 0.
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_unlock/3-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_unlock/3-1.c
index 4053388be..cb0ae72b6 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_unlock/3-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_unlock/3-1.c
@@ -6,8 +6,7 @@
* source tree.
* Test that pthread_mutex_unlock()
- * Upon succesful completion, it shall return zero
- *
+ * Upon successful completion, it shall return zero
*/
#include <pthread.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/pthread_sigmask/5-1.c b/testcases/open_posix_testsuite/conformance/interfaces/pthread_sigmask/5-1.c
index 63f6721c8..12f522e1f 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/pthread_sigmask/5-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/pthread_sigmask/5-1.c
@@ -5,7 +5,7 @@
* of this license, see the COPYING file at the top level of this
* source tree.
-The resulting set shall be the the signal set pointed to by set
+The resulting set shall be the signal set pointed to by set
Steps:
1. Have main create a new thread and wait for its termination.
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/raise/2-1.c b/testcases/open_posix_testsuite/conformance/interfaces/raise/2-1.c
index 1dfee2efe..005f46a4b 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/raise/2-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/raise/2-1.c
@@ -5,7 +5,7 @@
* of this license, see the COPYING file at the top level of this
* source tree.
- * Test that the the raise() function does not return until after the
+ * Test that the raise() function does not return until after the
* signal handler it calls returns.
* This test is only performed on one signal. All other signals are
* considered to be in the same equivalence class.
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-1.c b/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-1.c
index fb19ff6a4..ee106c677 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-1.c
@@ -24,10 +24,10 @@
* 5. Both children and father increment a counter in a basic loop.
* 6. The father send SIGTERM to the last child and get its counter. If child
* counter is reasonably lower than the fathers one, the test is
- * succesfull.
+ * successful.
* 7. The father kill all other children.
- *
*/
+
#include "affinity.h"
#include <sched.h>
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-2.c b/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-2.c
index 6c68120c3..c81ffd374 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/sched_setparam/2-2.c
@@ -24,9 +24,8 @@
* 5. Both children and father increment a counter in a basic loop.
* 6. The father send SIGTERM to the last child and get its counter. If child
* counter is reasonably lower than the fathers one, the test is
- * succesfull.
+ * successful.
* 7. The father kill all other children.
- *
*/
#include "affinity.h"
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/assertions.xml b/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/assertions.xml
index 37b96641b..86fc1d544 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/assertions.xml
+++ b/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/assertions.xml
@@ -5,7 +5,7 @@
</assertion>
<assertion id="2" tag="ref:XSH6:42291:42293 pt:RTS">
Error checking is performed but no signal is actually sent, if signo is zero (the null signal).
- Using the null signal can be used to check the the validity of pid.
+ Using the null signal can be used to check the validity of pid.
</assertion>
<assertion id="3" tag="ref:XSH6:42294:42295 pt:RTS">
For a process to have permission to queue a signal to another process
diff --git a/testcases/realtime/func/matrix_mult/matrix_mult.c b/testcases/realtime/func/matrix_mult/matrix_mult.c
index e2a55628a..c32092344 100644
--- a/testcases/realtime/func/matrix_mult/matrix_mult.c
+++ b/testcases/realtime/func/matrix_mult/matrix_mult.c
@@ -100,7 +100,7 @@ static void matrix_mult(struct matrices *matrices)
matrix_init(matrices->A, matrices->B);
for (i = 0; i < MATRIX_SIZE; i++) {
- int i_m = MATRIX_SIZE - i;
+ int i_m = MATRIX_SIZE - i - 1;
for (j = 0; j < MATRIX_SIZE; j++) {
double sum = matrices->A[i_m][j] * matrices->B[j][i];
for (k = 0; k < MATRIX_SIZE; k++)
diff --git a/testcases/realtime/tools/ftqviz.py b/testcases/realtime/tools/ftqviz.py
index 5ac094cbd..f56d41aa6 100644
--- a/testcases/realtime/tools/ftqviz.py
+++ b/testcases/realtime/tools/ftqviz.py
@@ -45,7 +45,7 @@ def smooth(x, wlen):
# generate the smoothed signal
y = convolve(w/w.sum(), s, mode='same')
- # recenter the the smoothed signal over the originals (slide along x)
+ # recenter the smoothed signal over the originals (slide along x)
y1 = y[wlen-1:-wlen+1]
return y1
diff --git a/testscripts/network.sh b/testscripts/network.sh
index 15a4cc1c7..afe9c7a97 100755
--- a/testscripts/network.sh
+++ b/testscripts/network.sh
@@ -86,13 +86,6 @@ if [ "$OPTIND" -eq 1 ]; then
fi
shift $(($OPTIND - 1))
-TST_NO_DEFAULT_RUN=1
-. tst_net.sh
-
-# Reset variables.
-# Don't break the tests which are using 'testcases/lib/cmdlib.sh'
-unset TST_ID TST_LIB_LOADED TST_NO_DEFAULT_RUN
-
rm -f $CMDFILE
for t in $TEST_CASES; do
diff --git a/tools/create-tarballs-metadata.sh b/tools/create-tarballs-metadata.sh
new file mode 100755
index 000000000..e7f93d5c0
--- /dev/null
+++ b/tools/create-tarballs-metadata.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+# Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+# Create tarballs and metadata for uploading after tagging release.
+# https://github.com/linux-test-project/ltp/wiki/LTP-Release-Procedure
+set -e
+
+tag="$(date +%Y%m%d)"
+tarball_dir="ltp-full-$tag"
+extensions="bz2 xz"
+checksums="md5 sha1 sha256"
+git_dir=$(cd $(dirname "$0")/..; pwd)
+dir="$(cd $git_dir/../; pwd)/ltp-release-$tag"
+
+. $(dirname "$0")/lib.sh
+
+if [ -d $dir ]; then
+ ask "Directory '$dir' exists, will be deleted"
+ rm -rf $dir
+fi
+rod mkdir $dir
+cd $dir
+dir=$PWD
+
+# git clone (local)
+title "git clone"
+rod git clone $git_dir $tarball_dir
+rod cd $tarball_dir
+
+title "Update submodules"
+rod git submodule update --init
+
+title "Generate configure script"
+rod make autotools
+
+# tarballs, checksums
+title "Generate tarballs"
+cd ..
+rod tar --exclude .git -cjf $tarball_dir.tar.bz2 $tarball_dir
+rod tar --exclude .git -cJf $tarball_dir.tar.xz $tarball_dir
+
+title "Generate checksums"
+for alg in $checksums; do
+ for ext in $extensions; do
+ file="$tarball_dir.tar.$ext"
+ ${alg}sum $file > "$file.$alg"
+ done
+done
+
+# metadata documentation
+title "Generate metadata documentation"
+cd $tarball_dir
+rod ./configure --with-metadata-generator=asciidoctor
+rod make -C metadata
+cp -v docparse/metadata.html $dir/metadata.$tag.html
+
+echo "Generated files are in '$dir', upload them to github"
diff --git a/tools/lib.sh b/tools/lib.sh
new file mode 100755
index 000000000..c96433d28
--- /dev/null
+++ b/tools/lib.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+# Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+
+ask()
+{
+ local msg="$1"
+ local answer
+
+ printf "\n$msg. Proceed? [N/y]: "
+ read answer
+ case "$answer" in
+ [Yy]*) : ;;
+ *) exit 2
+ esac
+}
+
+quit()
+{
+ printf "\n$@\n" >&2
+ exit 1
+}
+
+rod()
+{
+ eval "$@" || quit "$@ failed"
+}
+
+title()
+{
+ echo "===== $1 ====="
+}
diff --git a/tools/ltx/Makefile b/tools/ltx/Makefile
new file mode 100644
index 000000000..4810ec8df
--- /dev/null
+++ b/tools/ltx/Makefile
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2023 Cyril Hrubis <chrubis@suse.cz>
+# Copyright (c) 2023 Andrea Cervesato <andrea.cervesato@suse.com>
+#
+# Install script for Linux Test eXecutor
+
+top_srcdir ?= ../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+ifneq ($(wildcard $(abs_srcdir)/ltx-src/*),)
+
+BINARY=ltx
+
+MAKE_TARGETS := $(BINARY)
+
+CFLAGS+=-I$(abs_srcdir)/ltx-src/ -I$(abs_srcdir)/ltx-src/msgpack/
+
+$(BINARY): $(wildcard $(abs_srcdir)/ltx-src/*.c $(abs_srcdir)/ltx-src/msgpack/*.c)
+ifdef VERBOSE
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+else
+ @echo CC $@
+ @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+endif
+
+INSTALL_DIR := $(prefix)
+
+endif
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/tools/runltp-ng b/tools/runltp-ng
deleted file mode 160000
-Subproject e842511ed2c680e3b2ea6dec790913a41d5ed93
diff --git a/tools/tag-release.sh b/tools/tag-release.sh
new file mode 100755
index 000000000..2967c7b4d
--- /dev/null
+++ b/tools/tag-release.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# Copyright (c) 2023 Petr Vorel <pvorel@suse.cz>
+# Tag LTP release.
+# https://github.com/linux-test-project/ltp/wiki/LTP-Release-Procedure
+set -e
+
+upstream_git="linux-test-project/ltp"
+tag="$(date +%Y%m%d)"
+old_tag="$(git describe --abbrev=0)"
+tag_msg="LTP $tag"
+
+. $(dirname "$0")/lib.sh
+
+cd $(dirname "$0")/..
+
+if ! git ls-remote --get-url origin | grep -q $upstream_git; then
+ quit "Not an upstream project"
+fi
+
+if ! git --no-pager diff --exit-code; then
+ quit "Please commit your changes before making new release"
+fi
+
+if git show $tag 2> /dev/null; then
+ quit "Tag '$tag' already exists"
+fi
+
+if grep -q "$tag" VERSION; then
+ quit "Tag '$tag' already in VERSION file"
+fi
+
+title "git tag"
+echo "new tag: '$tag', previous tag: '$old_tag'"
+echo "$tag" > VERSION
+git add VERSION
+rod git commit -S --signoff --message \"$tag_msg\" VERSION
+rod git tag --sign --annotate $tag --message \"$tag_msg\"
+git --no-pager show $tag --show-signature
+
+ask "Please check tag and signature"
+
+title "git push"
+ask "Pushing changes to upstream git"
+rod git push origin master:master
+git push origin $tag
diff --git a/utils/benchmark/ebizzy-0.3/ebizzy.c b/utils/benchmark/ebizzy-0.3/ebizzy.c
index 54b047130..e7556dd56 100644
--- a/utils/benchmark/ebizzy-0.3/ebizzy.c
+++ b/utils/benchmark/ebizzy-0.3/ebizzy.c
@@ -50,6 +50,7 @@
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <stdint.h>
#include "ebizzy.h"
@@ -83,7 +84,6 @@ static char **hole_mem;
static unsigned int page_size;
static time_t start_time;
static volatile int threads_go;
-static unsigned int records_read;
static void usage(void)
{
@@ -366,13 +366,13 @@ static inline unsigned int rand_num(unsigned int max, unsigned int *state)
*
*/
-static unsigned int search_mem(void)
+static uintptr_t search_mem(void)
{
record_t key, *found;
record_t *src, *copy;
unsigned int chunk;
size_t copy_size = chunk_size;
- unsigned int i;
+ uintptr_t i;
unsigned int state = 0;
for (i = 0; threads_go == 1; i++) {
@@ -423,6 +423,8 @@ static unsigned int search_mem(void)
static void *thread_run(void *arg __attribute__((unused)))
{
+ uintptr_t records_thread;
+
if (verbose > 1)
printf("Thread started\n");
@@ -430,13 +432,13 @@ static void *thread_run(void *arg __attribute__((unused)))
while (threads_go == 0) ;
- records_read += search_mem();
+ records_thread = search_mem();
if (verbose > 1)
printf("Thread finished, %f seconds\n",
difftime(time(NULL), start_time));
- return NULL;
+ return (void *)records_thread;
}
static struct timeval difftimeval(struct timeval *end, struct timeval *start)
@@ -454,6 +456,7 @@ static void start_threads(void)
unsigned int i;
struct rusage start_ru, end_ru;
struct timeval usr_time, sys_time;
+ double records_per_sec = 0.0;
int err;
if (verbose)
@@ -484,18 +487,19 @@ static void start_threads(void)
*/
for (i = 0; i < threads; i++) {
- err = pthread_join(thread_array[i], NULL);
+ uintptr_t record_thread;
+ err = pthread_join(thread_array[i], (void *)&record_thread);
if (err) {
fprintf(stderr, "Error joining thread %d\n", i);
exit(1);
}
+ records_per_sec += ((double)record_thread / elapsed);
}
if (verbose)
printf("Threads finished\n");
- printf("%u records/s\n",
- (unsigned int)(((double)records_read) / elapsed));
+ printf("%tu records/s\n", (uintptr_t) records_per_sec);
usr_time = difftimeval(&end_ru.ru_utime, &start_ru.ru_utime);
sys_time = difftimeval(&end_ru.ru_stime, &start_ru.ru_stime);
diff --git a/ver_linux b/ver_linux
index 2df1c7b69..7dd0fe176 100755
--- a/ver_linux
+++ b/ver_linux
@@ -131,12 +131,16 @@ if [ -e /proc/modules ]; then
fi
echo
+echo 'cpuinfo:'
+tst_cmd_run lscpu || cat /proc/cpuinfo
+
+echo
echo 'free reports:'
free
echo
-echo 'cpuinfo:'
-tst_cmd_run lscpu || cat /proc/cpuinfo
+echo 'memory (/proc/meminfo):'
+cat /proc/meminfo
echo
echo 'available filesystems:'