/*
 * Copyright (c) International Business Machines  Corp., 2001
 *
 * This program is free software;  you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY;  without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 * the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program;  if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/*
 * NAME
 *	mprotect03.c
 *
 * DESCRIPTION
 *	Testcase to check the mprotect(2) system call.
 *
 * ALGORITHM
 *	Create a shared mapped file region with PROT_READ | PROT_WRITE
 *	using the mmap(2) call. Then, use mprotect(2) to disable the
 *	write permission on the mapped region. Then, attempt to write to
 *	the mapped region using memcpy(). This would generate a sigsegv.
 *	Since the sigsegv is generated, this needs to be done in a child
 *	process (as sigsegv would repeatedly be generated). The testcase
 *	succeeds only when this sigsegv is generated while attempting to
 *	memcpy() on a shared region with only read permission.
 *
 * HISTORY
 *	07/2001 Ported by Wayne Boyer
 *      05/2002 changed over to use tst_sig instead of sigaction
 */

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <limits.h>
#include <signal.h>
#include <wait.h>
#include "test.h"

#include "safe_macros.h"

#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
#define FAILED 1

static void cleanup(void);
static void setup(void);

char *TCID = "mprotect03";
int TST_TOTAL = 1;
int status;
char file1[BUFSIZ];

int main(int ac, char **av)
{
	int lc;
	const char *msg;

	char *addr;
	int fd, pid;
	char *buf = "abcdefghijklmnopqrstuvwxyz";

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;

		if ((fd = open(file1, O_RDWR | O_CREAT, 0777)) < 0)
			tst_brkm(TBROK, cleanup, "open failed");

		SAFE_WRITE(cleanup, 1, fd, buf, strlen(buf));

		/*
		 * mmap the PAGESIZE bytes as read only.
		 */
		addr = mmap(0, strlen(buf), PROT_READ | PROT_WRITE, MAP_SHARED,
			    fd, 0);
		if (addr == MAP_FAILED)
			tst_brkm(TBROK, cleanup, "mmap failed");

		/*
		 * Try to change the protection to WRITE.
		 */
		TEST(mprotect(addr, strlen(buf), PROT_READ));

		if (TEST_RETURN != -1) {
			if ((pid = FORK_OR_VFORK()) == -1) {
				tst_brkm(TBROK, cleanup, "fork failed");
			}

			if (pid == 0) {
				memcpy(addr, buf, strlen(buf));
				tst_resm(TINFO, "memcpy() did "
					 "not generate SIGSEGV");
				exit(1);
			}

			waitpid(pid, &status, 0);
			if (WEXITSTATUS(status) != 0) {
				tst_resm(TFAIL, "child returned "
					 "unexpected status");
			} else {
				tst_resm(TPASS, "SIGSEGV generated "
					 "as expected");
			}
		} else {
			tst_resm(TFAIL, "mprotect failed "
				 "unexpectedly, errno: %d", errno);
		}

		/* clean up things in case we are looping */
		if (munmap(addr, strlen(buf)) == -1) {
			tst_brkm(TBROK, cleanup, "munamp failed");
		}
		if (close(fd) == -1) {
			tst_brkm(TBROK, cleanup, "close failed");
		}
		if (unlink(file1) == -1) {
			tst_brkm(TBROK, cleanup, "unlink failed");
		}
	}

	cleanup();
	tst_exit();
}

static void sighandler(int sig)
{
	if (sig == SIGSEGV) {
		tst_resm(TINFO, "received signal: SIGSEGV");
		tst_exit();
	} else
		tst_brkm(TBROK, 0, "Unexpected signal %d received.", sig);
}

static void setup(void)
{
	tst_sig(FORK, sighandler, NULL);

	TEST_PAUSE;

	tst_tmpdir();

	sprintf(file1, "mprotect03.tmp.%d", getpid());
}

static void cleanup(void)
{
	tst_rmdir();
}
