Skip to content

Commit

Permalink
Merge tag 'linux-kselftest-5.2-rc1' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/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
  ...
  • Loading branch information
Linus Torvalds committed May 7, 2019
2 parents 81ff5d2 + d917fb8 commit 71ae5fc
Show file tree
Hide file tree
Showing 35 changed files with 1,081 additions and 223 deletions.
94 changes: 92 additions & 2 deletions Documentation/dev-tools/kselftest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
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)
=============================================================

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

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
============

The kselftest_harness.h file contains useful helpers to build tests. The tests
from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as example.
The kselftest_harness.h file contains useful helpers to build tests. The
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
-------
Expand Down
4 changes: 4 additions & 0 deletions include/linux/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ size_t strlcpy(char *, const char *, size_t);
#ifndef __HAVE_ARCH_STRSCPY
ssize_t strscpy(char *, const char *, size_t);
#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
extern char * strcat(char *, const char *);
#endif
Expand Down
3 changes: 3 additions & 0 deletions lib/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -1769,6 +1769,9 @@ config TEST_HEXDUMP
config TEST_STRING_HELPERS
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
tristate "Test kstrto*() family of functions at runtime"

Expand Down
1 change: 1 addition & 0 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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_PRINTF) += test_printf.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_UUID) += test_uuid.o
obj-$(CONFIG_TEST_XARRAY) += test_xarray.o
Expand Down
47 changes: 40 additions & 7 deletions lib/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,9 @@ EXPORT_SYMBOL(strlcpy);
* @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 routine returns the number of characters copied (not including
* the trailing NUL) or -E2BIG if the destination buffer wasn't big enough.
* The behavior is undefined if the string buffers overlap.
* The destination buffer is always NUL terminated, unless it's zero-sized.
* 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.
*
* Preferred to strlcpy() since the API doesn't require reading memory
* from the src string beyond the specified "count" bytes, and since
Expand All @@ -173,8 +171,10 @@ EXPORT_SYMBOL(strlcpy);
*
* Preferred to strncpy() since it always returns a valid string, and
* 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()
* with an overflow test, then just memset() the tail of the dest buffer.
* zeroed. If zeroing is desired please use strscpy_pad().
*
* 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)
{
Expand Down Expand Up @@ -237,6 +237,39 @@ ssize_t strscpy(char *dest, const char *src, size_t count)
EXPORT_SYMBOL(strscpy);
#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
/**
* strcat - Append one %NUL-terminated string to another
Expand Down
20 changes: 4 additions & 16 deletions lib/test_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <linux/slab.h>
#include <linux/string.h>

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

static unsigned total_tests __initdata;
static unsigned failed_tests __initdata;

Expand Down Expand Up @@ -361,30 +363,16 @@ static void noinline __init test_mem_optimisations(void)
}
}

static int __init test_bitmap_init(void)
static void __init selftest(void)
{
test_zero_clear();
test_fill_set();
test_copy();
test_bitmap_arr32();
test_bitmap_parselist();
test_mem_optimisations();

if (failed_tests == 0)
pr_info("all %u tests passed\n", total_tests);
else
pr_warn("failed %u out of %u tests\n",
failed_tests, total_tests);

return failed_tests ? -EINVAL : 0;
}

static void __exit test_bitmap_cleanup(void)
{
}

module_init(test_bitmap_init);
module_exit(test_bitmap_cleanup);

KSTM_MODULE_LOADERS(test_bitmap);
MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
MODULE_LICENSE("GPL");
17 changes: 5 additions & 12 deletions lib/test_printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <linux/gfp.h>
#include <linux/mm.h>

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

#define BUF_SIZE 256
#define PAD_SIZE 16
#define FILL_CHAR '$'
Expand Down Expand Up @@ -590,12 +592,11 @@ test_pointer(void)
flags();
}

static int __init
test_printf_init(void)
static void __init selftest(void)
{
alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL);
if (!alloced_buffer)
return -ENOMEM;
return;
test_buffer = alloced_buffer + PAD_SIZE;

test_basic();
Expand All @@ -604,16 +605,8 @@ test_printf_init(void)
test_pointer();

kfree(alloced_buffer);

if (failed_tests == 0)
pr_info("all %u tests passed\n", total_tests);
else
pr_warn("failed %u out of %u tests\n", failed_tests, total_tests);

return failed_tests ? -EINVAL : 0;
}

module_init(test_printf_init);

KSTM_MODULE_LOADERS(test_printf);
MODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>");
MODULE_LICENSE("GPL");
Loading

0 comments on commit 71ae5fc

Please sign in to comment.