All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Haines <richard_c_haines@btinternet.com>
To: selinux@vger.kernel.org
Cc: Richard Haines <richard_c_haines@btinternet.com>
Subject: [PATCH] selinux-testsuite: Add key_socket tests
Date: Sun, 10 Nov 2019 16:26:18 +0000	[thread overview]
Message-ID: <20191110162618.395932-1-richard_c_haines@btinternet.com> (raw)

Test relevant key management socket permissions.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
 defconfig                   |   4 ++
 policy/Makefile             |   4 ++
 policy/test_key_socket.te   |  74 +++++++++++++++++++
 tests/Makefile              |   4 ++
 tests/key_socket/.gitignore |   1 +
 tests/key_socket/Makefile   |   7 ++
 tests/key_socket/key_sock.c | 139 ++++++++++++++++++++++++++++++++++++
 tests/key_socket/test       |  45 ++++++++++++
 8 files changed, 278 insertions(+)
 create mode 100644 policy/test_key_socket.te
 create mode 100644 tests/key_socket/.gitignore
 create mode 100644 tests/key_socket/Makefile
 create mode 100644 tests/key_socket/key_sock.c
 create mode 100755 tests/key_socket/test

diff --git a/defconfig b/defconfig
index b13075d..0574f1d 100644
--- a/defconfig
+++ b/defconfig
@@ -74,3 +74,7 @@ CONFIG_BPF_SYSCALL=y
 CONFIG_KEYS=y
 CONFIG_KEYS_COMPAT=y
 CONFIG_KEY_DH_OPERATIONS=y
+
+# Test key management socket.
+# This is not required for SELinux operation itself.
+CONFIG_NET_KEY=m
diff --git a/policy/Makefile b/policy/Makefile
index ff65153..ad94c43 100644
--- a/policy/Makefile
+++ b/policy/Makefile
@@ -90,6 +90,10 @@ ifeq ($(shell grep -q all_file_perms.*watch $(POLDEV)/include/support/all_perms.
 TARGETS+=test_notify.te
 endif
 
+ifeq ($(shell grep -q key_socket $(POLDEV)/include/support/all_perms.spt && echo true),true)
+TARGETS += test_key_socket.te
+endif
+
 ifeq (x$(DISTRO),$(filter x$(DISTRO),xRHEL4 xRHEL5 xRHEL6))
 TARGETS:=$(filter-out test_overlayfs.te test_mqueue.te test_ibpkey.te, $(TARGETS))
 endif
diff --git a/policy/test_key_socket.te b/policy/test_key_socket.te
new file mode 100644
index 0000000..6906010
--- /dev/null
+++ b/policy/test_key_socket.te
@@ -0,0 +1,74 @@
+#
+############## Test key management socket 'key_socket' #####################
+#
+attribute keysockdomain;
+
+type test_key_sock_t;
+domain_type(test_key_sock_t)
+unconfined_runs_test(test_key_sock_t)
+typeattribute test_key_sock_t testdomain;
+typeattribute test_key_sock_t keysockdomain;
+
+# key_socket rules:
+allow test_key_sock_t self:rawip_socket { create };
+allow test_key_sock_t self:capability { net_admin };
+allow test_key_sock_t self:key_socket { create write read setopt };
+# For CONFIG_NET_KEY=m
+allow test_key_sock_t kernel_t:system { module_request };
+
+################## Deny capability { net_admin } ##########################
+#
+# Note that when capability { net_admin } is removed for the test
+# there will not be an audit message in the log as the Fedora policy
+# is built with 'hide_broken_symptoms' that adds the following:
+#   dontaudit test_key_sock_no_net_admin_t self:capability { net_admin sys_module };
+#
+type test_key_sock_no_net_admin_t;
+domain_type(test_key_sock_no_net_admin_t)
+unconfined_runs_test(test_key_sock_no_net_admin_t)
+typeattribute test_key_sock_no_net_admin_t testdomain;
+typeattribute test_key_sock_no_net_admin_t keysockdomain;
+
+allow test_key_sock_no_net_admin_t self:rawip_socket { create };
+allow test_key_sock_no_net_admin_t self:key_socket { create write read setopt };
+allow test_key_sock_no_net_admin_t kernel_t:system { module_request };
+
+####################### Deny key_socket { create } ##########################
+type test_key_sock_no_create_t;
+domain_type(test_key_sock_no_create_t)
+unconfined_runs_test(test_key_sock_no_create_t)
+typeattribute test_key_sock_no_create_t testdomain;
+typeattribute test_key_sock_no_create_t keysockdomain;
+
+allow test_key_sock_no_create_t self:rawip_socket { create };
+allow test_key_sock_no_create_t self:capability { net_admin };
+allow test_key_sock_no_create_t self:key_socket { write read setopt };
+
+####################### Deny key_socket { write } ##########################
+type test_key_sock_no_write_t;
+domain_type(test_key_sock_no_write_t)
+unconfined_runs_test(test_key_sock_no_write_t)
+typeattribute test_key_sock_no_write_t testdomain;
+typeattribute test_key_sock_no_write_t keysockdomain;
+
+allow test_key_sock_no_write_t self:rawip_socket { create };
+allow test_key_sock_no_write_t self:capability { net_admin };
+allow test_key_sock_no_write_t self:key_socket { create read setopt };
+allow test_key_sock_no_write_t kernel_t:system { module_request };
+
+####################### Deny key_socket { read } ##########################
+type test_key_sock_no_read_t;
+domain_type(test_key_sock_no_read_t)
+unconfined_runs_test(test_key_sock_no_read_t)
+typeattribute test_key_sock_no_read_t testdomain;
+typeattribute test_key_sock_no_read_t keysockdomain;
+
+allow test_key_sock_no_read_t self:rawip_socket { create };
+allow test_key_sock_no_read_t self:capability { net_admin };
+allow test_key_sock_no_read_t self:key_socket { create write setopt };
+allow test_key_sock_no_read_t kernel_t:system { module_request };
+#
+########### Allow these domains to be entered from sysadm domain ############
+#
+miscfiles_domain_entry_test_files(keysockdomain)
+userdom_sysadm_entry_spec_domtrans_to(keysockdomain)
diff --git a/tests/Makefile b/tests/Makefile
index 0021590..cca6648 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -52,6 +52,10 @@ ifeq ($(shell grep -q all_key_perms $(POLDEV)/include/support/all_perms.spt && e
 SUBDIRS += keys
 endif
 
+ifeq ($(shell grep -q key_socket $(POLDEV)/include/support/all_perms.spt && test -e $(INCLUDEDIR)/keyutils.h && echo true),true)
+SUBDIRS += key_socket
+endif
+
 ifeq ($(shell grep "^SELINUX_INFINIBAND_ENDPORT_TEST=" infiniband_endport/ibendport_test.conf | cut -d'=' -f 2),1)
 SUBDIRS += infiniband_endport
 endif
diff --git a/tests/key_socket/.gitignore b/tests/key_socket/.gitignore
new file mode 100644
index 0000000..1a532c0
--- /dev/null
+++ b/tests/key_socket/.gitignore
@@ -0,0 +1 @@
+key_sock
diff --git a/tests/key_socket/Makefile b/tests/key_socket/Makefile
new file mode 100644
index 0000000..e5e6a58
--- /dev/null
+++ b/tests/key_socket/Makefile
@@ -0,0 +1,7 @@
+TARGETS = key_sock
+LDLIBS += -lselinux
+
+all: $(TARGETS)
+
+clean:
+	rm -f $(TARGETS)
diff --git a/tests/key_socket/key_sock.c b/tests/key_socket/key_sock.c
new file mode 100644
index 0000000..95622b7
--- /dev/null
+++ b/tests/key_socket/key_sock.c
@@ -0,0 +1,139 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <linux/pfkeyv2.h>
+#include <selinux/selinux.h>
+
+static void print_usage(char *progname)
+{
+	fprintf(stderr,
+		"usage:  %s [-v]\n"
+		"Where:\n\t"
+		"-v  Print information.\n", progname);
+	exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+	char *context;
+	int opt, sock, result;
+	bool verbose = false;
+	struct timeval tm;
+	struct sadb_msg w_msg, r_msg;
+	int mlen = sizeof(struct sadb_msg);
+
+	while ((opt = getopt(argc, argv, "v")) != -1) {
+		switch (opt) {
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			print_usage(argv[0]);
+		}
+	}
+
+	result = getcon(&context);
+	if (result < 0) {
+		fprintf(stderr, "Failed to obtain process context\n");
+		exit(1);
+	}
+
+	if (verbose)
+		printf("Process context:\n\t%s\n", context);
+
+	sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
+	if (sock < 0) {
+		fprintf(stderr, "Failed to open key management socket: %s\n",
+			strerror(errno));
+		/* Return errno as denying net_admin=EPERM, create=EACCES */
+		exit(errno);
+	}
+
+	if (verbose)
+		printf("Opened key management socket\n");
+
+	/* Set socket timeout for read in case no response from kernel */
+	tm.tv_sec = 3;
+	tm.tv_usec = 0;
+	result = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm));
+	if (result < 0) {
+		fprintf(stderr, "Failed setsockopt SO_RCVTIMEO: %s\n",
+			strerror(errno));
+		result = 2;
+		goto error;
+	}
+
+	if (verbose)
+		printf("setsocketopt: SO_RCVTIMEO - %ld seconds\n", tm.tv_sec);
+
+	memset(&w_msg, 0, mlen);
+	w_msg.sadb_msg_version = PF_KEY_V2;
+	w_msg.sadb_msg_type = SADB_FLUSH;
+	w_msg.sadb_msg_satype = SADB_SATYPE_AH;
+	/* sadb_msg_len contains length in 64-bit words */
+	w_msg.sadb_msg_len = (mlen / sizeof(uint64_t));
+	w_msg.sadb_msg_seq = 99;
+	w_msg.sadb_msg_pid = getpid();
+
+	result = write(sock, &w_msg, mlen);
+	if (result < 0) {
+		fprintf(stderr, "Failed write to key management socket: %s\n",
+			strerror(errno));
+		result = 3;
+		goto error;
+	}
+
+	if (verbose) {
+		printf("Write sadb_msg data to key management socket:\n");
+		printf("\tver: PF_KEY_V2 type: SADB_FLUSH sa_type: SADB_SATYPE_AH\n");
+		printf("\tseq: %d pid: %d\n", w_msg.sadb_msg_seq,
+		       w_msg.sadb_msg_pid);
+	}
+
+	memset(&r_msg, 0, mlen);
+
+	result = read(sock, &r_msg, mlen);
+	if (result < 0) {
+		fprintf(stderr, "Failed to read key management socket: %s\n",
+			strerror(errno));
+		result = 4;
+		goto error;
+	}
+
+	if (r_msg.sadb_msg_version != w_msg.sadb_msg_version ||
+	    r_msg.sadb_msg_type != w_msg.sadb_msg_type ||
+	    r_msg.sadb_msg_satype != w_msg.sadb_msg_satype ||
+	    r_msg.sadb_msg_seq != w_msg.sadb_msg_seq ||
+	    r_msg.sadb_msg_pid != getpid()) {
+		fprintf(stderr, "Failed to read correct sadb_msg data:\n");
+		fprintf(stderr, "\tSent - ver: %d type: %d sa_type: %d seq: %d pid: %d\n",
+			w_msg.sadb_msg_version, w_msg.sadb_msg_type,
+			w_msg.sadb_msg_satype, w_msg.sadb_msg_seq,
+			w_msg.sadb_msg_pid);
+		fprintf(stderr, "\tRecv - ver: %d type: %d sa_type: %d seq: %d pid: %d\n",
+			r_msg.sadb_msg_version, r_msg.sadb_msg_type,
+			r_msg.sadb_msg_satype, r_msg.sadb_msg_seq,
+			r_msg.sadb_msg_pid);
+		result = 5;
+		goto error;
+	}
+
+	if (verbose) {
+		printf("Read sadb_msg data from key management socket:\n");
+		printf("\tver: PF_KEY_V2 type: SADB_FLUSH sa_type: SADB_SATYPE_AH\n");
+		printf("\tseq: %d pid: %d\n", r_msg.sadb_msg_seq,
+		       r_msg.sadb_msg_pid);
+	}
+
+	result = 0;
+
+error:
+	close(sock);
+
+	return result;
+}
diff --git a/tests/key_socket/test b/tests/key_socket/test
new file mode 100755
index 0000000..9772611
--- /dev/null
+++ b/tests/key_socket/test
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+use Test::More;
+
+BEGIN {
+    $basedir = $0;
+    $basedir =~ s|(.*)/[^/]*|$1|;
+
+    # allow info to be shown during tests
+    $v = $ARGV[0];
+    if ($v) {
+        if ( $v ne "-v" ) {
+            plan skip_all => "Invalid option (use -v)";
+        }
+    }
+    else {
+        $v = " ";
+    }
+
+    plan tests => 5;
+}
+
+############ Test key_socket #############
+print "Test key_socket class\n";
+$result = system "runcon -t test_key_sock_t $basedir/key_sock $v";
+ok( $result eq 0 );
+
+# Deny capability { net_admin } - EPERM
+$result =
+  system "runcon -t test_key_sock_no_net_admin_t $basedir/key_sock $v 2>&1";
+ok( $result >> 8 eq 1 );
+
+# Deny key_socket { create } - EACCES
+$result =
+  system "runcon -t test_key_sock_no_create_t $basedir/key_sock $v 2>&1";
+ok( $result >> 8 eq 13 );
+
+# Deny key_socket { write }
+$result = system "runcon -t test_key_sock_no_write_t $basedir/key_sock $v 2>&1";
+ok( $result >> 8 eq 3 );
+
+# Deny key_socket { read }
+$result = system "runcon -t test_key_sock_no_read_t $basedir/key_sock $v 2>&1";
+ok( $result >> 8 eq 4 );
+
+exit;
-- 
2.23.0


                 reply	other threads:[~2019-11-10 16:26 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191110162618.395932-1-richard_c_haines@btinternet.com \
    --to=richard_c_haines@btinternet.com \
    --cc=selinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.