diff mbox

[1/2] selinux-testsuite: Infiniband pkey tests

Message ID 1495047273-96339-2-git-send-email-danielj@mellanox.com (mailing list archive)
State Superseded
Headers show

Commit Message

Daniel Jurgens May 17, 2017, 6:54 p.m. UTC
From: Daniel Jurgens <danielj@mellanox.com>

New tests for infiniband pkeys. Most users don't have Infiniband
hardware, and if they do the pkey configuration is not standardized.
There is a configuration file for enabling the test and setting
environment specific test configurations. If the tests are disable they
will always show as passed.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
---
 README                                   |   9 ++
 policy/Makefile                          |   3 +-
 policy/test_ibpkey.te                    |  23 +++++
 tests/Makefile                           |   4 +-
 tests/infiniband_pkey/Makefile           |   7 ++
 tests/infiniband_pkey/create_modify_qp.c | 144 +++++++++++++++++++++++++++++++
 tests/infiniband_pkey/ibpkey_test.conf   |  14 +++
 tests/infiniband_pkey/test               |  45 ++++++++++
 8 files changed, 246 insertions(+), 3 deletions(-)
 create mode 100644 policy/test_ibpkey.te
 create mode 100644 tests/infiniband_pkey/Makefile
 create mode 100644 tests/infiniband_pkey/create_modify_qp.c
 create mode 100644 tests/infiniband_pkey/ibpkey_test.conf
 create mode 100644 tests/infiniband_pkey/test
diff mbox

Patch

diff --git a/README b/README
index deedae5..b64e2de 100644
--- a/README
+++ b/README
@@ -195,3 +195,12 @@  establish a base directory (based on the path of the script
 executable).  This won't always be accurate, but will work for this
 test harness/configuration.
 	$basedir = $0;  $basedir =~ s|(.*)/[^/]*|$1|;
+
+INFINIBAND TESTS
+----------------
+Because running Infiniband tests requires specialized hardware you must
+set up a configuration file for these tests. The tests are disabled by
+default.  See comments in the configuration file for info.
+
+Infiniband PKey test conf file:
+tests/infiniband_pkey/ibpkey_test.conf
diff --git a/policy/Makefile b/policy/Makefile
index 661f27a..ab58d3b 100644
--- a/policy/Makefile
+++ b/policy/Makefile
@@ -20,7 +20,8 @@  TARGETS = \
 	test_task_create.te test_task_getpgid.te test_task_getsched.te \
 	test_task_getsid.te test_task_setpgid.te test_task_setsched.te \
 	test_transition.te test_inet_socket.te test_unix_socket.te \
-	test_mmap.te test_overlayfs.te test_mqueue.te test_mac_admin.te
+	test_mmap.te test_overlayfs.te test_mqueue.te test_mac_admin.te \
+	test_ibpkey.te
 
 ifeq ($(shell [ $(POL_VERS) -ge 24 ] && echo true),true)
 TARGETS += test_bounds.te
diff --git a/policy/test_ibpkey.te b/policy/test_ibpkey.te
new file mode 100644
index 0000000..0ff6da4
--- /dev/null
+++ b/policy/test_ibpkey.te
@@ -0,0 +1,23 @@ 
+#################################
+#
+# Policy for testing Infiniband Pkey access.
+#
+
+attribute ibpkeydomain;
+
+# Domain for process.
+type test_ibpkey_modify_t;
+domain_type(test_ibpkey_modify_t)
+unconfined_runs_test(test_ibpkey_modify_t)
+typeattribute test_ibpkey_modify_t testdomain;
+typeattribute test_ibpkey_modify_t ibpkeydomain;
+
+dev_rw_infiniband_dev(test_ibpkey_modify_t)
+dev_rw_sysfs(test_ibpkey_modify_t)
+
+# client can connect to the server via the socket file or via abstract sockets.
+corenet_ibpkey_access_default_pkey(test_ibpkey_modify_t)
+
+# Allow all of these domains to be entered from the sysadm domain.
+miscfiles_domain_entry_test_files(ibpkeydomain)
+userdom_sysadm_entry_spec_domtrans_to(ibpkeydomain)
diff --git a/tests/Makefile b/tests/Makefile
index fb8a0aa..7dfe2a8 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -4,13 +4,13 @@  export CFLAGS+=-g -O0 -Wall -D_GNU_SOURCE
 
 DISTRO=$(shell ./os_detect)
 
-SUBDIRS:=domain_trans entrypoint execshare exectrace execute_no_trans \
+SUBDIRS:= domain_trans entrypoint execshare exectrace execute_no_trans \
 	fdreceive inherit link mkdir msg open ptrace readlink relabel rename \
 	rxdir sem setattr setnice shm sigkill stat sysctl task_create \
 	task_setnice task_setscheduler task_getscheduler task_getsid \
 	task_getpgid task_setpgid file ioctl capable_file capable_net \
 	capable_sys dyntrans dyntrace bounds nnp mmap unix_socket inet_socket \
-	overlay checkreqprot mqueue mac_admin
+	overlay checkreqprot mqueue mac_admin infiniband_pkey
 
 ifeq ($(shell grep -q cap_userns $(POLDEV)/include/support/all_perms.spt && echo true),true)
 ifneq ($(shell ./kvercmp $$(uname -r) 4.7),-1)
diff --git a/tests/infiniband_pkey/Makefile b/tests/infiniband_pkey/Makefile
new file mode 100644
index 0000000..60f0d24
--- /dev/null
+++ b/tests/infiniband_pkey/Makefile
@@ -0,0 +1,7 @@ 
+TARGETS=create_modify_qp
+
+LDLIBS+= -libverbs
+
+all: $(TARGETS)
+clean:
+	rm -f $(TARGETS)
diff --git a/tests/infiniband_pkey/create_modify_qp.c b/tests/infiniband_pkey/create_modify_qp.c
new file mode 100644
index 0000000..495ef5b
--- /dev/null
+++ b/tests/infiniband_pkey/create_modify_qp.c
@@ -0,0 +1,144 @@ 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <infiniband/verbs.h>
+
+struct ibv_qp	   *qp;
+struct ibv_context *context;
+struct ibv_pd      *pd;
+struct ibv_cq      *cq;
+struct ibv_srq     *srq;
+
+void cleanup_ib_rsrc()
+{
+	ibv_destroy_qp(qp);
+	ibv_destroy_srq(srq);
+	ibv_destroy_cq(cq);
+	ibv_dealloc_pd(pd);
+	ibv_close_device(context);
+}
+
+int init_ib_rsrc(char* deviceName)
+{
+	int                 ndev = 0;
+	struct ibv_device  **dlist = ibv_get_device_list(&ndev);
+	struct ibv_device  *device = NULL;;
+	struct ibv_srq_init_attr srqiattr;
+	struct ibv_qp_init_attr qpiattr;
+	int i;
+
+	if (!ndev)
+	{
+		fprintf(stderr, "No IB devices found.\n");
+		exit(1);
+	}
+
+	for (i = 0; i < ndev; i++)
+		if(!strcmp(deviceName, dlist[i]->name))
+			device = dlist[i];
+
+	if (!device)
+	{
+		fprintf(stderr, "Couldn't find device %s\n", deviceName);
+		exit(1);
+	}
+	/* Open context */
+	context = ibv_open_device(device);
+	if (NULL == context)
+	{
+		fprintf(stderr, "Unable to open device.\n");
+		exit(1);
+	}
+
+	/* Allocate PD */
+	pd = ibv_alloc_pd(context);
+	if (!pd)
+	{
+		fprintf(stderr, "Unable to allocate PD.\n");
+		exit(1);
+	}
+
+	/* Create CQ */
+	cq = ibv_create_cq(context, 2048, NULL, NULL, 0);
+	if (!cq)
+	{
+		fprintf(stderr, "Unable to create cq.\n");
+		exit(1);
+	}
+
+	/* Create SRQ */
+	memset(&srqiattr, 0, sizeof(srqiattr));
+	srqiattr.attr.max_wr    = 2048;
+	srqiattr.attr.max_sge   = 4;
+	srqiattr.attr.srq_limit = 1024;
+	srq = ibv_create_srq(pd, &srqiattr);
+	if (NULL == srq)
+	{
+		fprintf(stderr, "Unable to create sreq.\n");
+		exit(1);
+	}
+
+	memset(&qpiattr, 0, sizeof(qpiattr));
+	qpiattr.send_cq = cq;
+	qpiattr.recv_cq = cq;
+	qpiattr.srq     = srq;
+	qpiattr.cap.max_send_wr = 128;
+	qpiattr.cap.max_recv_wr = 4;
+	qpiattr.cap.max_send_sge = 5;
+	qpiattr.cap.max_recv_sge = 4;
+	qpiattr.cap.max_inline_data = 512;
+	qpiattr.qp_type = IBV_QPT_RC;
+	qpiattr.sq_sig_all = 1;
+	qp = ibv_create_qp(pd, &qpiattr);
+
+	if (!qp)
+	{
+		fprintf(stderr, "Unable to create QP %d.\n", i);
+		exit(1);
+	}
+
+	return 0;
+}
+
+int init_rc_qp(uint8_t port, uint16_t pkey_index)
+{
+	struct ibv_qp_attr attr = {
+	         .qp_state        = IBV_QPS_INIT,
+	         .pkey_index      = pkey_index,
+	         .port_num        = port,
+	         .qp_access_flags = 0
+	};
+
+	return ibv_modify_qp(qp, &attr,
+			     IBV_QP_STATE |
+			     IBV_QP_PKEY_INDEX |
+			     IBV_QP_PORT |
+			     IBV_QP_ACCESS_FLAGS);
+}
+
+int main(int argc, char *argv[])
+{
+	uint16_t pkey_index;
+	uint8_t port;
+	int ret;
+
+	if (argc != 4)
+	{
+		printf("Please enter <ib device name> <port number> <pkey index>\n");
+		exit(1);
+	}
+	port = atoi(argv[2]);
+	pkey_index = atoi(argv[3]);
+
+	init_ib_rsrc(argv[1]);
+
+	ret = init_rc_qp(port, pkey_index);
+	cleanup_ib_rsrc();
+	exit(ret);
+}
diff --git a/tests/infiniband_pkey/ibpkey_test.conf b/tests/infiniband_pkey/ibpkey_test.conf
new file mode 100644
index 0000000..ac4e9cc
--- /dev/null
+++ b/tests/infiniband_pkey/ibpkey_test.conf
@@ -0,0 +1,14 @@ 
+# Enable(1)/Disable these tests
+SELINUX_INFINIBAND_PKEY_TEST=0
+
+# Infiniband device to use.
+SELINUX_INFINIBAND_PKEY_TEST_DEV=mlx5_3
+
+# Physical port on the device to use.
+SELINUX_INFINIBAND_PKEY_TEST_PORT=1
+
+# CSV list of pkeys indexes that should be allowed.
+SELINUX_INFINIBAND_TEST_ALLOWED_PKEYS=0
+
+# CSV list of pkey indexes that should fail.
+SELINUX_INFINIBAND_TEST_DENIED_PKEYS=1,2,3
diff --git a/tests/infiniband_pkey/test b/tests/infiniband_pkey/test
new file mode 100644
index 0000000..89d1a7c
--- /dev/null
+++ b/tests/infiniband_pkey/test
@@ -0,0 +1,45 @@ 
+#!/usr/bin/perl
+
+use Test;
+
+BEGIN { plan tests => 2}
+
+$basedir = $0; $basedir =~ s|(.*)/[^/]*|$1|;
+
+my %conf;
+my $confpath = $basedir."/ibpkey_test.conf";
+open($f, $confpath) or die ("Couldn't open $confpath");
+while($r = <$f>) {
+	if ($r =~ /^\s*#/ || $r =~ /^\s*$/) { next; }
+	chomp $r;
+	($k,$v) = split(/=/, $r);
+	$conf{$k} = $v;
+}
+
+if ($conf{SELINUX_INFINIBAND_PKEY_TEST} eq 1) {
+	$device = $conf{SELINUX_INFINIBAND_PKEY_TEST_DEV};
+	$port = $conf{SELINUX_INFINIBAND_PKEY_TEST_PORT};
+	@allowed_pkeys = split(/,/, $conf{SELINUX_INFINIBAND_TEST_ALLOWED_PKEYS});
+	@denied_pkeys = split(/,/, $conf{SELINUX_INFINIBAND_TEST_DENIED_PKEYS});
+
+	foreach (@allowed_pkeys) {
+		$result = system "runcon -t test_ibpkey_modify_t $basedir/create_modify_qp $device $port $_";
+		if($result ne 0) {
+			last;
+		}
+	}
+	ok($result, 0);
+
+	foreach (@denied_pkeys) {
+		$result = system "runcon -t test_ibpkey_modify_t $basedir/create_modify_qp $device $port $_";
+		if ($result>>8 ne 13) {
+			last;
+		}
+	}
+
+	ok($result>>8, 13);
+} else {
+	ok(1, 0);
+	ok(1, 0);
+}
+exit;