[LTP] [PATCH v3] security/stack_clash: Add test for mmap() minding gap
Petr Vorel
pvorel@suse.cz
Wed Jul 12 10:09:36 CEST 2023
Hi Rick,
Reviewed-by: Petr Vorel <pvorel@suse.cz>
...
> This logic is somewhat x86_64 specific, but may work for other
> architectures. Make the test only run on x86_64 for now.
...
> v3:
> - Use lapi/mmap.h (Petr Vorel)
> v2:
> - Add fixes commit (Cyril Hrubis)
> - Report placement test failure separately (Cyril Hrubis)
> - Use SAFE_FILE_SCANF (Cyril Hrubis)
> - Don't quit after failing placement test, so unmap the mapping that
> caused the failure. (Cyril Hrubis)
> - Drop CAN_DO_PLACEMENT_TEST (Cyril Hrubis)
> ---
> testcases/cve/stack_clash.c | 81 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 80 insertions(+), 1 deletion(-)
nit: You might want to add your copyright.
> diff --git a/testcases/cve/stack_clash.c b/testcases/cve/stack_clash.c
> index cd7f148c2..50a401e96 100644
> --- a/testcases/cve/stack_clash.c
> +++ b/testcases/cve/stack_clash.c
> @@ -18,11 +18,18 @@
> * 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
> */
Doc could be turned into our docparse format (to place text in our automatically
generated documentation), but I can do it afterwards.
...
> +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 +252,11 @@ void do_child(void)
> dump_proc_self_maps();
> #endif
> +#ifdef __x86_64__
I wonder whether we should consider 32 bit as well:
#if defined(__x86_64__) || defined(__i386__)
Or is it really just for 64 bit?
> + do_mmap_placement_test(stack_addr, gap);
> +#endif
...
Kind regards,
Petr
More information about the ltp
mailing list