[LTP] [PATCH v2] syscalls/brk: add direct syscall tst_variant
Richard Palethorpe
rpalethorpe@suse.de
Mon Dec 12 16:12:04 CET 2022
Cyril, Petr, Would you like to add your reviewed by tags? Then we can
merge this.
Teo Couprie Diaz <teo.coupriediaz@arm.com> writes:
> Direct usage of brk is discouraged in favor of using malloc. Also, brk was
> removed from POSIX in POSIX.1-2001.
> In particular, the Musl libc's brk always returns -ENOMEM which causes
> the LTP tests to exit prematurely. Invoking the syscall directly allows
> them to properly validate brk behavior. Add a new test variant handling if
> the libc wrappers are not implemented and testing the direct syscall.
>
> Use tst_syscall() and handle the failure cases ourselves, as
> we don't depend on the libc to do it anymore.
>
> The patch also works around the dependency on sbrk to get the current break
> as it has the same issues. Instead, call tst_syscall(__NR_brk, 0) which
> always returns the current break.
>
> Update brk01 to use void* to unify it with brk02.
>
> Signed-off-by: Teo Couprie Diaz <teo.coupriediaz@arm.com>
> ---
> v1: Reworked from RFC by adding a variant rather than replacing the
> existing tests. Thanks Petr and Cyril !
> v2: brk doesn't return the new break, just if it error'd or not.
> Fix styling and warnings.
>
> testcases/kernel/syscalls/brk/brk01.c | 37 ++++++++++++++++------
> testcases/kernel/syscalls/brk/brk02.c | 44 ++++++++++++++++++++++-----
> 2 files changed, 65 insertions(+), 16 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/brk/brk01.c b/testcases/kernel/syscalls/brk/brk01.c
> index a9b89bce5..93e430328 100644
> --- a/testcases/kernel/syscalls/brk/brk01.c
> +++ b/testcases/kernel/syscalls/brk/brk01.c
> @@ -9,14 +9,31 @@
> #include <errno.h>
>
> #include "tst_test.h"
> +#include "lapi/syscalls.h"
>
> void verify_brk(void)
> {
> - uintptr_t cur_brk, new_brk;
> - uintptr_t inc = getpagesize() * 2 - 1;
> + void *cur_brk, *new_brk;
> + size_t inc = getpagesize() * 2 - 1;
> unsigned int i;
>
> - cur_brk = (uintptr_t)sbrk(0);
> + if (tst_variant) {
> + tst_res(TINFO, "Testing syscall variant");
> + cur_brk = (void *)tst_syscall(__NR_brk, 0);
> + } else {
> + tst_res(TINFO, "Testing libc variant");
> + cur_brk = (void *)sbrk(0);
> +
> + if (cur_brk == (void *)-1)
> + tst_brk(TCONF, "sbrk() not implemented");
> +
> + /*
> + * Check if brk itself is implemented: updating to the current break
> + * should be a no-op.
> + */
> + if (brk(cur_brk) != 0)
> + tst_brk(TCONF, "brk() not implemented");
> + }
>
> for (i = 0; i < 33; i++) {
> switch (i % 3) {
> @@ -31,16 +48,17 @@ void verify_brk(void)
> break;
> }
>
> - TST_EXP_PASS_SILENT(brk((void *)new_brk), "brk()");
> - if (!TST_PASS)
> - return;
> -
> - cur_brk = (uintptr_t)sbrk(0);
> + if (tst_variant) {
> + cur_brk = (void *)tst_syscall(__NR_brk, new_brk);
> + } else {
> + TST_EXP_PASS_SILENT(brk(new_brk), "brk()");
> + cur_brk = sbrk(0);
> + }
>
> if (cur_brk != new_brk) {
> tst_res(TFAIL,
> "brk() failed to set address have %p expected %p",
> - (void *)cur_brk, (void *)new_brk);
> + cur_brk, new_brk);
> return;
> }
>
> @@ -54,4 +72,5 @@ void verify_brk(void)
>
> static struct tst_test test = {
> .test_all = verify_brk,
> + .test_variants = 2,
> };
> diff --git a/testcases/kernel/syscalls/brk/brk02.c b/testcases/kernel/syscalls/brk/brk02.c
> index 11e803cb4..3a97d279b 100644
> --- a/testcases/kernel/syscalls/brk/brk02.c
> +++ b/testcases/kernel/syscalls/brk/brk02.c
> @@ -14,24 +14,53 @@
> #include <unistd.h>
> #include <sys/mman.h>
> #include "tst_test.h"
> +#include "lapi/syscalls.h"
> +
> +void *brk_variants(void *addr)
> +{
> + void *brk_addr;
> +
> + if (tst_variant) {
> + brk_addr = (void *)tst_syscall(__NR_brk, addr);
> + } else {
> + TST_EXP_PASS_SILENT(brk(addr), "brk()");
> + brk_addr = (void *)sbrk(0);
> + }
> + return brk_addr;
> +}
>
> void brk_down_vmas(void)
> {
> - void *brk_addr = sbrk(0);
> + void *brk_addr;
> +
> + if (tst_variant) {
> + tst_res(TINFO, "Testing syscall variant");
> + brk_addr = (void *)tst_syscall(__NR_brk, 0);
> + } else {
> + tst_res(TINFO, "Testing libc variant");
> + brk_addr = (void *)sbrk(0);
>
> - if (brk_addr == (void *) -1)
> - tst_brk(TBROK, "sbrk() failed");
> + if (brk_addr == (void *)-1)
> + tst_brk(TCONF, "sbrk() not implemented");
> +
> + /*
> + * Check if brk itself is implemented: updating to the current break
> + * should be a no-op.
> + */
> + if (brk(brk_addr) != 0)
> + tst_brk(TCONF, "brk() not implemented");
> + }
>
> unsigned long page_size = getpagesize();
> void *addr = brk_addr + page_size;
>
> - if (brk(addr)) {
> + if (brk_variants(addr) < addr) {
> tst_res(TFAIL | TERRNO, "Cannot expand brk() by page size");
> return;
> }
>
> addr += page_size;
> - if (brk(addr)) {
> + if (brk_variants(addr) < addr) {
> tst_res(TFAIL | TERRNO, "Cannot expand brk() by 2x page size");
> return;
> }
> @@ -42,12 +71,12 @@ void brk_down_vmas(void)
> }
>
> addr += page_size;
> - if (brk(addr)) {
> + if (brk_variants(addr) < addr) {
> tst_res(TFAIL | TERRNO, "Cannot expand brk() after mprotect");
> return;
> }
>
> - if (brk(brk_addr)) {
> + if (brk_variants(brk_addr) != brk_addr) {
> tst_res(TFAIL | TERRNO, "Cannot restore brk() to start address");
> return;
> }
> @@ -57,4 +86,5 @@ void brk_down_vmas(void)
>
> static struct tst_test test = {
> .test_all = brk_down_vmas,
> + .test_variants = 2,
> };
>
> base-commit: 990c0b48f8508a747863b1dea5556fba57e1c304
> --
> 2.25.1
--
Thank you,
Richard.
More information about the ltp
mailing list