/*
 * Callbacks for user-supplied memory allocation, supplemental
 * auditing, and locking routines.
 *
 * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil>
 *
 * Netlink code derived in part from sample code by
 * James Morris <jmorris@redhat.com>.
 */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include "callbacks.h"
#include "selinux_netlink.h"
#include "avc_internal.h"
#include "selinux_internal.h"

#ifndef NETLINK_SELINUX
#define NETLINK_SELINUX 7
#endif

/* callback pointers */
void *(*avc_func_malloc) (size_t) = NULL;
void (*avc_func_free) (void *) = NULL;

void (*avc_func_log) (const char *, ...) = NULL;
void (*avc_func_audit) (void *, security_class_t, char *, size_t) = NULL;

int avc_using_threads = 0;
int avc_app_main_loop = 0;
void *(*avc_func_create_thread) (void (*)(void)) = NULL;
void (*avc_func_stop_thread) (void *) = NULL;

void *(*avc_func_alloc_lock) (void) = NULL;
void (*avc_func_get_lock) (void *) = NULL;
void (*avc_func_release_lock) (void *) = NULL;
void (*avc_func_free_lock) (void *) = NULL;

/* message prefix string and avc enforcing mode */
char avc_prefix[AVC_PREFIX_SIZE] = "uavc";
int avc_running = 0;
int avc_enforcing = 1;
int avc_setenforce = 0;
int avc_netlink_trouble = 0;

/* netlink socket code */
static int fd = -1;

int avc_netlink_open(int blocking)
{
	int len, rc = 0;
	struct sockaddr_nl addr;

	fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_SELINUX);
	if (fd < 0) {
		rc = fd;
		goto out;
	}
	
	if (!blocking && fcntl(fd, F_SETFL, O_NONBLOCK)) {
		close(fd);
		fd = -1;
		rc = -1;
		goto out;
	}

	len = sizeof(addr);

	memset(&addr, 0, len);
	addr.nl_family = AF_NETLINK;
	addr.nl_groups = SELNL_GRP_AVC;

	if (bind(fd, (struct sockaddr *)&addr, len) < 0) {
		close(fd);
		fd = -1;
		rc = -1;
		goto out;
	}
      out:
	return rc;
}

void avc_netlink_close(void)
{
	if (fd >= 0)
		close(fd);
	fd = -1;
}

static int avc_netlink_receive(void *buf, unsigned buflen, int blocking)
{
	int rc;
	struct pollfd pfd = { fd, POLLIN | POLLPRI, 0 };
	struct sockaddr_nl nladdr;
	socklen_t nladdrlen = sizeof nladdr;
	struct nlmsghdr *nlh = (struct nlmsghdr *)buf;

	do {
		rc = poll(&pfd, 1, (blocking ? -1 : 0));
	} while (rc < 0 && errno == EINTR);

	if (rc == 0 && !blocking) {
		errno = EWOULDBLOCK;
		return -1;
	}
	else if (rc < 1) {
		avc_log(SELINUX_ERROR, "%s:  netlink poll: error %d\n",
			avc_prefix, errno);
		return rc;
	}

	rc = recvfrom(fd, buf, buflen, 0, (struct sockaddr *)&nladdr,
		      &nladdrlen);
	if (rc < 0)
		return rc;

	if (nladdrlen != sizeof nladdr) {
		avc_log(SELINUX_WARNING,
			"%s:  warning: netlink address truncated, len %u?\n",
			avc_prefix, nladdrlen);
		return -1;
	}

	if (nladdr.nl_pid) {
		avc_log(SELINUX_WARNING,
			"%s:  warning: received spoofed netlink packet from: %u\n",
			avc_prefix, nladdr.nl_pid);
		return -1;
	}

	if (rc == 0) {
		avc_log(SELINUX_WARNING,
			"%s:  warning: received EOF on netlink socket\n",
			avc_prefix);
		errno = EBADFD;
		return -1;
	}

	if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > (unsigned)rc) {
		avc_log(SELINUX_WARNING,
			"%s:  warning: incomplete netlink message\n",
			avc_prefix);
		return -1;
	}

	return 0;
}

static int avc_netlink_process(void *buf)
{
	int rc;
	struct nlmsghdr *nlh = (struct nlmsghdr *)buf;

	switch (nlh->nlmsg_type) {
	case NLMSG_ERROR:{
		struct nlmsgerr *err = NLMSG_DATA(nlh);

		/* Netlink ack */
		if (err->error == 0)
			break;

		errno = -err->error;
		avc_log(SELINUX_ERROR,
			"%s:  netlink error: %d\n", avc_prefix, errno);
		return -1;
	}

	case SELNL_MSG_SETENFORCE:{
		struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh);
		msg->val = !!msg->val;
		avc_log(SELINUX_INFO,
			"%s:  received setenforce notice (enforcing=%d)\n",
			avc_prefix, msg->val);
		if (avc_setenforce)
			break;
		avc_enforcing = msg->val;
		if (avc_enforcing && (rc = avc_ss_reset(0)) < 0) {
			avc_log(SELINUX_ERROR,
				"%s:  cache reset returned %d (errno %d)\n",
				avc_prefix, rc, errno);
			return rc;
		}
		rc = selinux_netlink_setenforce(msg->val);
		if (rc < 0)
			return rc;
		break;
	}

	case SELNL_MSG_POLICYLOAD:{
		struct selnl_msg_policyload *msg = NLMSG_DATA(nlh);
		avc_log(SELINUX_INFO,
			"%s:  received policyload notice (seqno=%u)\n",
			avc_prefix, msg->seqno);
		rc = avc_ss_reset(msg->seqno);
		if (rc < 0) {
			avc_log(SELINUX_ERROR,
				"%s:  cache reset returned %d (errno %d)\n",
				avc_prefix, rc, errno);
			return rc;
		}
		selinux_flush_class_cache();
		rc = selinux_netlink_policyload(msg->seqno);
		if (rc < 0)
			return rc;
		break;
	}

	default:
		avc_log(SELINUX_WARNING,
			"%s:  warning: unknown netlink message %d\n",
			avc_prefix, nlh->nlmsg_type);
	}
	return 0;
}

int avc_netlink_check_nb(void)
{
	int rc;
	char buf[1024] __attribute__ ((aligned));

	while (1) {
		errno = 0;
		rc = avc_netlink_receive(buf, sizeof(buf), 0);
		if (rc < 0) {
			if (errno == EWOULDBLOCK)
				return 0;
			if (errno == 0 || errno == EINTR)
				continue;
			else {
				avc_log(SELINUX_ERROR,
					"%s:  netlink recvfrom: error %d\n",
					avc_prefix, errno);
				return rc;
			}
		}

		(void)avc_netlink_process(buf);
	}
	return 0;
}

/* run routine for the netlink listening thread */
void avc_netlink_loop(void)
{
	int rc;
	char buf[1024] __attribute__ ((aligned));

	while (1) {
		errno = 0;
		rc = avc_netlink_receive(buf, sizeof(buf), 1);
		if (rc < 0) {
			if (errno == 0 || errno == EINTR)
				continue;
			else {
				avc_log(SELINUX_ERROR,
					"%s:  netlink recvfrom: error %d\n",
					avc_prefix, errno);
				break;
			}
		}

		rc = avc_netlink_process(buf);
		if (rc < 0)
			break;
	}

	close(fd);
	fd = -1;
	avc_netlink_trouble = 1;
	avc_log(SELINUX_ERROR,
		"%s:  netlink thread: errors encountered, terminating\n",
		avc_prefix);
}

int avc_netlink_acquire_fd(void)
{
    avc_app_main_loop = 1;

    return fd;
}

void avc_netlink_release_fd(void)
{
    avc_app_main_loop = 0;
}
