/*
 * Copyright (C) 2013 Linux Test Project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it
 * is free of the rightful claim of any third person regarding
 * infringement or the like.  Any license provided herein, whether
 * implied or otherwise, applies only to this software file.  Patent
 * licenses, if any, provided herein do not apply to combinations of
 * this program with other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
/*
 * reproducer for:
 * BUG: unable to handle kernel NULL ptr deref in selinux_socket_unix_may_send
 * fixed in 3.9.0-0.rc5:
 *   commit ded34e0fe8fe8c2d595bfa30626654e4b87621e0
 *   Author: Paul Moore <pmoore@redhat.com>
 *   Date:   Mon Mar 25 03:18:33 2013 +0000
 *     unix: fix a race condition in unix_release()
 */

#define _GNU_SOURCE
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include "config.h"
#include "test.h"
#include "safe_macros.h"

union semun {
	int val;
	struct semid_ds *buf;
	unsigned short int *array;
};

char *TCID = "sendmsg02";

static int sem_id;
static int tflag;
static char *t_opt;
static option_t options[] = {
	{"s:", &tflag, &t_opt},
	{NULL, NULL, NULL}
};

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

static void client(int id, int pipefd[])
{
	int fd, semval;
	char data[] = "123456789";
	struct iovec w;
	struct sockaddr_un sa;
	struct msghdr mh;
	struct cmsghdr cmh;

	close(pipefd[0]);

	memset(&sa, 0, sizeof(sa));
	sa.sun_family = AF_UNIX;
	snprintf(sa.sun_path, sizeof(sa.sun_path), "socket_test%d", id);

	w.iov_base = data;
	w.iov_len = 10;

	memset(&cmh, 0, sizeof(cmh));
	mh.msg_control = &cmh;
	mh.msg_controllen = sizeof(cmh);

	memset(&mh, 0, sizeof(mh));
	mh.msg_name = &sa;
	mh.msg_namelen = sizeof(struct sockaddr_un);
	mh.msg_iov = &w;
	mh.msg_iovlen = 1;

	do {
		fd = socket(AF_UNIX, SOCK_DGRAM, 0);
		write(pipefd[1], &fd, 1);
		sendmsg(fd, &mh, MSG_NOSIGNAL);
		close(fd);
		semval = semctl(sem_id, 0, GETVAL);
	} while (semval != 0);
	close(pipefd[1]);
}

static void server(int id, int pipefd[])
{
	int fd, semval;
	struct sockaddr_un sa;

	close(pipefd[1]);

	memset(&sa, 0, sizeof(sa));
	sa.sun_family = AF_UNIX;
	snprintf(sa.sun_path, sizeof(sa.sun_path), "socket_test%d", id);

	do {
		fd = socket(AF_UNIX, SOCK_DGRAM, 0);
		unlink(sa.sun_path);
		bind(fd, (struct sockaddr *) &sa, sizeof(struct sockaddr_un));
		read(pipefd[0], &fd, 1);
		close(fd);
		semval = semctl(sem_id, 0, GETVAL);
	} while (semval != 0);
	close(pipefd[0]);
}

static void reproduce(int seconds)
{
	int i, status, pipefd[2];
	int child_pairs = sysconf(_SC_NPROCESSORS_ONLN)*4;
	int child_count = 0;
	int *child_pids;
	int child_pid;
	union semun u;

	child_pids = SAFE_MALLOC(cleanup, sizeof(int) * child_pairs * 2);

	u.val = 1;
	if (semctl(sem_id, 0, SETVAL, u) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "couldn't set semval to 1");

	/* fork child for each client/server pair */
	for (i = 0; i < child_pairs*2; i++) {
		if (i%2 == 0) {
			if (pipe(pipefd) < 0) {
				tst_resm(TBROK | TERRNO, "pipe failed");
				break;
			}
		}

		child_pid = fork();
		switch (child_pid) {
		case -1:
			tst_resm(TBROK | TERRNO, "fork");
			break;
		case 0:
			if (i%2 == 0)
				server(i, pipefd);
			else
				client(i-1, pipefd);
			exit(0);
		default:
			child_pids[child_count++] = child_pid;
		};

		/* this process can close the pipe now */
		if (i%2 == 0) {
			close(pipefd[0]);
			close(pipefd[1]);
		}
	}

	/* let clients/servers run for a while, then clear semval to signal
	 * they should stop running now */
	if (child_count == child_pairs*2)
		sleep(seconds);

	u.val = 0;
	if (semctl(sem_id, 0, SETVAL, u) == -1) {
		/* kill children if setting semval failed */
		for (i = 0; i < child_count; i++)
			kill(child_pids[i], SIGKILL);
		tst_resm(TBROK | TERRNO, "couldn't set semval to 0");
	}

	for (i = 0; i < child_count; i++) {
		if (waitpid(child_pids[i], &status, 0) == -1)
			tst_resm(TBROK | TERRNO, "waitpid for %d failed",
				child_pids[i]);
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child %d returns %d", i, status);
	}
	free(child_pids);
}

static void help(void)
{
	printf("  -s NUM  Number of seconds to run.\n");
}

int main(int argc, char *argv[])
{
	int lc;
	const char *msg;
	long seconds;

	msg = parse_opts(argc, argv, options, &help);
	if (msg != NULL)
		tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
	setup();

	seconds = tflag ? SAFE_STRTOL(NULL, t_opt, 1, LONG_MAX) : 15;
	for (lc = 0; TEST_LOOPING(lc); lc++)
		reproduce(seconds);
	tst_resm(TPASS, "finished after %ld seconds", seconds);

	cleanup();
	tst_exit();
}

static void setup(void)
{
	tst_require_root(NULL);
	tst_tmpdir();

	sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRWXU);
	if (sem_id == -1)
		tst_brkm(TBROK | TERRNO, NULL, "Couldn't allocate semaphore");

	TEST_PAUSE;
}

static void cleanup(void)
{
	semctl(sem_id, 0, IPC_RMID);
	tst_rmdir();
}
