/*
 *
 *   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
 *	kill05.c
 *
 * DESCRIPTION
 *	Test case to check that kill() fails when passed a pid owned by another
 *	user.
 *
 * ALGORITHM
 *	call setup
 *	loop if the -i option was given
 *	setup a shared memory segment to for a flag which will notify
 *	ltpuser1's process that life is not worth living in a continuous loop.
 *	fork a child and set the euid to ltpuser1
 *	set the parents euid to ltpuser2
 *	execute the kill system call on ltpuser1's pid
 *	check the return value
 *	if return value is not -1
 *		issue a FAIL message, break remaining tests and cleanup
 *      if we are doing functional testing
 *              if the errno was set to 1 (Operation not permitted)
 *                      issue a PASS message
 *              otherwise
 *                      issue a FAIL message
 *	call cleanup
 *
 * USAGE
 *  kill05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
 *     where,  -c n : Run n copies concurrently.
 *             -e   : Turn on errno logging.
 *             -i n : Execute test n times.
 *             -I x : Execute test for x seconds.
 *             -P x : Pause for x seconds between iterations.
 *             -t   : Turn on syscall timing.
 *
 * HISTORY
 *	07/2001 Ported by Wayne Boyer
 *
 *      26/02/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
 *      - Fix wrong return value check on shmat system call (leading to
 *        segfault in case of error with this syscall).
 *      - Fix deletion of IPC memory segment. Segment was not correctly
 *        deleted due to the change of uid during the test.
 *
 * RESTRICTIONS
 *	This test must be run as root.
 *	Looping with the -i option does not work correctly.
 */

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "test.h"
#include "safe_macros.h"

extern void rm_shm(int);

void cleanup(void);
void setup(void);
void do_child(void);
void do_master_child(char **av);

char *TCID = "kill05";
int TST_TOTAL = 1;
int shmid1 = -1;
extern key_t semkey;
int *flag;

extern int getipckey();

#define TEST_SIG SIGKILL

int main(int ac, char **av)
{
	const char *msg;
	pid_t pid;
	int status;

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
#ifdef UCLINUX
	maybe_run_child(&do_child, "");
#endif

	setup();		/* global setup */

	pid = FORK_OR_VFORK();
	if (pid == -1)
		tst_brkm(TBROK, cleanup, "Fork failed");
	else if (pid == 0)
		do_master_child(av);

	if (waitpid(pid, &status, 0) == -1)
		tst_resm(TBROK | TERRNO, "waitpid failed");
	else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
		tst_resm(TFAIL, "child exited abnormally");
	else
		tst_resm(TPASS, "received expected errno(EPERM)");
	cleanup();
	tst_exit();
}

void wait_for_flag(int value)
{
	while (1) {
		if (*flag == value)
			break;
		else
			sleep(1);
	}
}

/*
 * do_master_child()
 */
void do_master_child(char **av)
{
	pid_t pid1;
	int status;

	char user1name[] = "nobody";
	char user2name[] = "bin";

	struct passwd *ltpuser1, *ltpuser2;

	tst_count = 0;

	*flag = 0;

	pid1 = FORK_OR_VFORK();

	if (pid1 == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "Fork failed");

	if (pid1 == 0) {
		ltpuser1 = SAFE_GETPWNAM(NULL, user1name);
		if (setreuid(ltpuser1->pw_uid, ltpuser1->pw_uid) == -1) {
			perror("setreuid failed (in child)");
			exit(1);
		}
		*flag = 1;
#ifdef UCLINUX
		if (self_exec(av[0], "") < 0) {
			perror("self_exec failed");
			exit(1);
		}
#else
		do_child();
#endif
	}
	ltpuser2 = SAFE_GETPWNAM(NULL, user2name);
	if (setreuid(ltpuser2->pw_uid, ltpuser2->pw_uid) == -1) {
		perror("seteuid failed");
		exit(1);
	}

	/* wait until child sets its euid */
	wait_for_flag(1);

	TEST(kill(pid1, TEST_SIG));

	/* signal the child that we're done */
	*flag = 2;

	if (waitpid(pid1, &status, 0) == -1) {
		perror("waitpid failed");
		exit(1);
	}

	if (TEST_RETURN != -1) {
		printf("kill succeeded unexpectedly\n");
		exit(1);
	}

	/*
	 * Check to see if the errno was set to the expected
	 * value of 1 : EPERM
	 */
	if (TEST_ERRNO == EPERM) {
		printf("kill failed with EPERM\n");
		exit(0);
	}
	perror("kill failed unexpectedly");
	exit(1);
}

void do_child(void)
{
	wait_for_flag(2);
	exit(0);
}

void setup(void)
{
	tst_require_root(NULL);

	TEST_PAUSE;

	tst_tmpdir();

	semkey = getipckey();

	if ((shmid1 = shmget(semkey, getpagesize(), 0666 | IPC_CREAT)) == -1)
		tst_brkm(TBROK, cleanup, "Failed to setup shared memory");

	if ((flag = shmat(shmid1, 0, 0)) == (int *)-1)
		tst_brkm(TBROK | TERRNO, cleanup,
			 "Failed to attach shared memory:%d", shmid1);
}

void cleanup(void)
{
	rm_shm(shmid1);

	tst_rmdir();
}
