brintos

brintos / linux-shallow public Read only

0
0
Text · 2.3 KiB · c8b32a2 Raw
119 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Test that signal delivery is able to expand the stack segment without4 * triggering a SEGV.5 *6 * Based on test code by Tom Lane.7 */8 9#include <err.h>10#include <stdio.h>11#include <stdlib.h>12#include <signal.h>13#include <sys/types.h>14#include <unistd.h>15 16#include "../pmu/lib.h"17#include "utils.h"18 19#define _KB (1024)20#define _MB (1024 * 1024)21 22static char *stack_base_ptr;23static char *stack_top_ptr;24 25static volatile sig_atomic_t sig_occurred = 0;26 27static void sigusr1_handler(int signal_arg)28{29	sig_occurred = 1;30}31 32static int consume_stack(unsigned int stack_size, union pipe write_pipe)33{34	char stack_cur;35 36	if ((stack_base_ptr - &stack_cur) < stack_size)37		return consume_stack(stack_size, write_pipe);38	else {39		stack_top_ptr = &stack_cur;40 41		FAIL_IF(notify_parent(write_pipe));42 43		while (!sig_occurred)44			barrier();45	}46 47	return 0;48}49 50static int child(unsigned int stack_size, union pipe write_pipe)51{52	struct sigaction act;53	char stack_base;54 55	act.sa_handler = sigusr1_handler;56	sigemptyset(&act.sa_mask);57	act.sa_flags = 0;58	if (sigaction(SIGUSR1, &act, NULL) < 0)59		err(1, "sigaction");60 61	stack_base_ptr = (char *) (((size_t) &stack_base + 65535) & ~65535UL);62 63	FAIL_IF(consume_stack(stack_size, write_pipe));64 65	printf("size 0x%06x: OK, stack base %p top %p (%zx used)\n",66		stack_size, stack_base_ptr, stack_top_ptr,67		stack_base_ptr - stack_top_ptr);68 69	return 0;70}71 72static int test_one_size(unsigned int stack_size)73{74	union pipe read_pipe, write_pipe;75	pid_t pid;76 77	FAIL_IF(pipe(read_pipe.fds) == -1);78	FAIL_IF(pipe(write_pipe.fds) == -1);79 80	pid = fork();81	if (pid == 0) {82		close(read_pipe.read_fd);83		close(write_pipe.write_fd);84		exit(child(stack_size, read_pipe));85	}86 87	close(read_pipe.write_fd);88	close(write_pipe.read_fd);89	FAIL_IF(sync_with_child(read_pipe, write_pipe));90 91	kill(pid, SIGUSR1);92 93	FAIL_IF(wait_for_child(pid));94 95	close(read_pipe.read_fd);96	close(write_pipe.write_fd);97 98	return 0;99}100 101int test(void)102{103	unsigned int i, size;104 105	// Test with used stack from 1MB - 64K to 1MB + 64K106	// Increment by 64 to get more coverage of odd sizes107	for (i = 0; i < (128 * _KB); i += 64) {108		size = i + (1 * _MB) - (64 * _KB);109		FAIL_IF(test_one_size(size));110	}111 112	return 0;113}114 115int main(void)116{117	return test_harness(test, "stack_expansion_signal");118}119