Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71ae5fc8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'linux-kselftest-5.2-rc1' of...

Merge tag 'linux-kselftest-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull Kselftest updates from Shuah Khan:

 - fixes to seccomp test, and kselftest framework

 - cleanups to remove duplicate header defines

 - fixes to efivarfs "make clean" target

 - cgroup cleanup path

 - Moving the IMA kexec_load selftest to selftests/kexec work from Mimi
   Johar and Petr Vorel

 - A framework to kselftest for writing kernel test modules addition
   from Tobin C. Harding

* tag 'linux-kselftest-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (29 commits)
  selftests: build and run gpio when output directory is the src dir
  selftests/ipc: Fix msgque compiler warnings
  selftests/efivarfs: clean up test files from test_create*()
  selftests: fix headers_install circular dependency
  selftests/kexec: update get_secureboot_mode
  selftests/kexec: make kexec_load test independent of IMA being enabled
  selftests/kexec: check kexec_load and kexec_file_load are enabled
  selftests/kexec: Add missing '=y' to config options
  selftests/kexec: kexec_file_load syscall test
  selftests/kexec: define "require_root_privileges"
  selftests/kexec: define common logging functions
  selftests/kexec: define a set of common functions
  selftests/kexec: cleanup the kexec selftest
  selftests/kexec: move the IMA kexec_load selftest to selftests/kexec
  selftests/harness: Add 30 second timeout per test
  selftests/seccomp: Handle namespace failures gracefully
  selftests: cgroup: fix cleanup path in test_memcg_subtree_control()
  selftests: efivarfs: remove the test_create_read file if it was exist
  rseq/selftests: Adapt number of threads to the number of detected cpus
  lib: Add test module for strscpy_pad
  ...
parents 81ff5d2c d917fb87
Loading
Loading
Loading
Loading
+92 −2
Original line number Original line Diff line number Diff line
@@ -14,6 +14,10 @@ in safe mode with a limited scope. In limited mode, cpu-hotplug test is
run on a single cpu as opposed to all hotplug capable cpus, and memory
run on a single cpu as opposed to all hotplug capable cpus, and memory
hotplug test is run on 2% of hotplug capable memory instead of 10%.
hotplug test is run on 2% of hotplug capable memory instead of 10%.


kselftest runs as a userspace process.  Tests that can be written/run in
userspace may wish to use the `Test Harness`_.  Tests that need to be
run in kernel space may wish to use a `Test Module`_.

Running the selftests (hotplug tests are run in limited mode)
Running the selftests (hotplug tests are run in limited mode)
=============================================================
=============================================================


@@ -161,11 +165,97 @@ Contributing new tests (details)


   e.g: tools/testing/selftests/android/config
   e.g: tools/testing/selftests/android/config


Test Module
===========

Kselftest tests the kernel from userspace.  Sometimes things need
testing from within the kernel, one method of doing this is to create a
test module.  We can tie the module into the kselftest framework by
using a shell script test runner.  ``kselftest_module.sh`` is designed
to facilitate this process.  There is also a header file provided to
assist writing kernel modules that are for use with kselftest:

- ``tools/testing/kselftest/kselftest_module.h``
- ``tools/testing/kselftest/kselftest_module.sh``

How to use
----------

Here we show the typical steps to create a test module and tie it into
kselftest.  We use kselftests for lib/ as an example.

1. Create the test module

2. Create the test script that will run (load/unload) the module
   e.g. ``tools/testing/selftests/lib/printf.sh``

3. Add line to config file e.g. ``tools/testing/selftests/lib/config``

4. Add test script to makefile  e.g. ``tools/testing/selftests/lib/Makefile``

5. Verify it works:

.. code-block:: sh

   # Assumes you have booted a fresh build of this kernel tree
   cd /path/to/linux/tree
   make kselftest-merge
   make modules
   sudo make modules_install
   make TARGETS=lib kselftest

Example Module
--------------

A bare bones test module might look like this:

.. code-block:: c

   // SPDX-License-Identifier: GPL-2.0+

   #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

   #include "../tools/testing/selftests/kselftest_module.h"

   KSTM_MODULE_GLOBALS();

   /*
    * Kernel module for testing the foobinator
    */

   static int __init test_function()
   {
           ...
   }

   static void __init selftest(void)
   {
           KSTM_CHECK_ZERO(do_test_case("", 0));
   }

   KSTM_MODULE_LOADERS(test_foo);
   MODULE_AUTHOR("John Developer <jd@fooman.org>");
   MODULE_LICENSE("GPL");

Example test script
-------------------

.. code-block:: sh

    #!/bin/bash
    # SPDX-License-Identifier: GPL-2.0+
    $(dirname $0)/../kselftest_module.sh "foo" test_foo


Test Harness
Test Harness
============
============


The kselftest_harness.h file contains useful helpers to build tests.  The tests
The kselftest_harness.h file contains useful helpers to build tests.  The
from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as example.
test harness is for userspace testing, for kernel space testing see `Test
Module`_ above.

The tests from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as
example.


Example
Example
-------
-------
+4 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,10 @@ size_t strlcpy(char *, const char *, size_t);
#ifndef __HAVE_ARCH_STRSCPY
#ifndef __HAVE_ARCH_STRSCPY
ssize_t strscpy(char *, const char *, size_t);
ssize_t strscpy(char *, const char *, size_t);
#endif
#endif

/* Wraps calls to strscpy()/memset(), no arch specific code required */
ssize_t strscpy_pad(char *dest, const char *src, size_t count);

#ifndef __HAVE_ARCH_STRCAT
#ifndef __HAVE_ARCH_STRCAT
extern char * strcat(char *, const char *);
extern char * strcat(char *, const char *);
#endif
#endif
+3 −0
Original line number Original line Diff line number Diff line
@@ -1769,6 +1769,9 @@ config TEST_HEXDUMP
config TEST_STRING_HELPERS
config TEST_STRING_HELPERS
	tristate "Test functions located in the string_helpers module at runtime"
	tristate "Test functions located in the string_helpers module at runtime"


config TEST_STRSCPY
	tristate "Test strscpy*() family of functions at runtime"

config TEST_KSTRTOX
config TEST_KSTRTOX
	tristate "Test kstrto*() family of functions at runtime"
	tristate "Test kstrto*() family of functions at runtime"


+1 −0
Original line number Original line Diff line number Diff line
@@ -81,6 +81,7 @@ obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
obj-$(CONFIG_TEST_PRINTF) += test_printf.o
obj-$(CONFIG_TEST_PRINTF) += test_printf.o
obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
obj-$(CONFIG_TEST_STRSCPY) += test_strscpy.o
obj-$(CONFIG_TEST_BITFIELD) += test_bitfield.o
obj-$(CONFIG_TEST_BITFIELD) += test_bitfield.o
obj-$(CONFIG_TEST_UUID) += test_uuid.o
obj-$(CONFIG_TEST_UUID) += test_uuid.o
obj-$(CONFIG_TEST_XARRAY) += test_xarray.o
obj-$(CONFIG_TEST_XARRAY) += test_xarray.o
+40 −7
Original line number Original line Diff line number Diff line
@@ -159,11 +159,9 @@ EXPORT_SYMBOL(strlcpy);
 * @src: Where to copy the string from
 * @src: Where to copy the string from
 * @count: Size of destination buffer
 * @count: Size of destination buffer
 *
 *
 * Copy the string, or as much of it as fits, into the dest buffer.
 * Copy the string, or as much of it as fits, into the dest buffer.  The
 * The routine returns the number of characters copied (not including
 * behavior is undefined if the string buffers overlap.  The destination
 * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough.
 * buffer is always NUL terminated, unless it's zero-sized.
 * The behavior is undefined if the string buffers overlap.
 * The destination buffer is always NUL terminated, unless it's zero-sized.
 *
 *
 * Preferred to strlcpy() since the API doesn't require reading memory
 * Preferred to strlcpy() since the API doesn't require reading memory
 * from the src string beyond the specified "count" bytes, and since
 * from the src string beyond the specified "count" bytes, and since
@@ -173,8 +171,10 @@ EXPORT_SYMBOL(strlcpy);
 *
 *
 * Preferred to strncpy() since it always returns a valid string, and
 * Preferred to strncpy() since it always returns a valid string, and
 * doesn't unnecessarily force the tail of the destination buffer to be
 * doesn't unnecessarily force the tail of the destination buffer to be
 * zeroed.  If the zeroing is desired, it's likely cleaner to use strscpy()
 * zeroed.  If zeroing is desired please use strscpy_pad().
 * with an overflow test, then just memset() the tail of the dest buffer.
 *
 * Return: The number of characters copied (not including the trailing
 *         %NUL) or -E2BIG if the destination buffer wasn't big enough.
 */
 */
ssize_t strscpy(char *dest, const char *src, size_t count)
ssize_t strscpy(char *dest, const char *src, size_t count)
{
{
@@ -237,6 +237,39 @@ ssize_t strscpy(char *dest, const char *src, size_t count)
EXPORT_SYMBOL(strscpy);
EXPORT_SYMBOL(strscpy);
#endif
#endif


/**
 * strscpy_pad() - Copy a C-string into a sized buffer
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @count: Size of destination buffer
 *
 * Copy the string, or as much of it as fits, into the dest buffer.  The
 * behavior is undefined if the string buffers overlap.  The destination
 * buffer is always %NUL terminated, unless it's zero-sized.
 *
 * If the source string is shorter than the destination buffer, zeros
 * the tail of the destination buffer.
 *
 * For full explanation of why you may want to consider using the
 * 'strscpy' functions please see the function docstring for strscpy().
 *
 * Return: The number of characters copied (not including the trailing
 *         %NUL) or -E2BIG if the destination buffer wasn't big enough.
 */
ssize_t strscpy_pad(char *dest, const char *src, size_t count)
{
	ssize_t written;

	written = strscpy(dest, src, count);
	if (written < 0 || written == count - 1)
		return written;

	memset(dest + written + 1, 0, count - written - 1);

	return written;
}
EXPORT_SYMBOL(strscpy_pad);

#ifndef __HAVE_ARCH_STRCAT
#ifndef __HAVE_ARCH_STRCAT
/**
/**
 * strcat - Append one %NUL-terminated string to another
 * strcat - Append one %NUL-terminated string to another
Loading