@@ -68,8 +68,9 @@ libselinux-devel # to build some of the test programs
net-tools # for ifconfig, used by capable_net/test
netlabel_tools # to load NetLabel configuration during inet_socket tests
iptables # to load iptables SECMARK rules during inet_socket tests
+libibverbs-devel # to build ibpkey test program.
-yum install perl-Test perl-Test-Harness perl-Test-Simple selinux-policy-devel gcc libselinux-devel net-tools netlabel_tools iptables
+yum install perl-Test perl-Test-Harness perl-Test-Simple selinux-policy-devel gcc libselinux-devel net-tools netlabel_tools iptables libibverbs-devel
The testsuite requires a pre-existing base policy configuration of
SELinux, using either the old example policy or the reference policy
@@ -195,3 +196,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
@@ -22,7 +22,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
new file mode 100644
@@ -0,0 +1,30 @@
+#################################
+#
+# Policy for testing Infiniband Pkey access.
+#
+
+attribute ibpkeydomain;
+
+# Domain for process.
+type test_ibpkey_access_t;
+domain_type(test_ibpkey_access_t)
+unconfined_runs_test(test_ibpkey_access_t)
+typeattribute test_ibpkey_access_t testdomain;
+typeattribute test_ibpkey_access_t ibpkeydomain;
+
+dev_rw_infiniband_dev(test_ibpkey_access_t)
+dev_rw_sysfs(test_ibpkey_access_t)
+
+# Define a pkey type for labeling pkeys during the test.
+type test_ibpkey_t;
+ifdef(`corenet_ib_pkey',`
+corenet_ib_pkey(test_ibpkey_t)
+')
+
+ifdef(`corenet_ib_access_unlabeled_pkeys',`
+corenet_ib_access_unlabeled_pkeys(test_ibpkey_access_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)
@@ -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)
new file mode 100644
@@ -0,0 +1,7 @@
+TARGETS=create_modify_qp
+
+LDLIBS+= -libverbs
+
+all: $(TARGETS)
+clean:
+ rm -f $(TARGETS)
new file mode 100644
@@ -0,0 +1,136 @@
+#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);
+}
new file mode 100644
@@ -0,0 +1,18 @@
+# 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 pkey table indexes containing labeled PKeys
+# These will not be allowed.
+SELINUX_INFINIBAND_TEST_LABELED_PKEYS=
+
+# CSV list of pkey table indexes containing unlabelde PKeys
+# This will be allowed, then temporarily labeled to see that
+# they are disallowed.
+SELINUX_INFINIBAND_TEST_UNLABELED_PKEYS=0
+
new file mode 100644
@@ -0,0 +1,84 @@
+#!/usr/bin/perl
+
+use Test;
+
+BEGIN { plan tests => 3}
+
+$basedir = $0; $basedir =~ s|(.*)/[^/]*|$1|;
+
+my %conf;
+$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;
+}
+close($f);
+
+if ($conf{SELINUX_INFINIBAND_PKEY_TEST} eq 1) {
+ $device = $conf{SELINUX_INFINIBAND_PKEY_TEST_DEV};
+ $port = $conf{SELINUX_INFINIBAND_PKEY_TEST_PORT};
+
+ # Read GID 0, to get the subnet prefix.
+ $gid_path = "/sys/class/infiniband/".$device."/ports/".$port."/gids/0";
+ open($f, $gid_path) or die ("Couldn't open $gid_path");
+ $gid = <$f>;
+ close($f);
+ # The gid sysfs shows a fully expanded ipv6 address, just take the
+ # top half.
+ @tmp = unpack('(a20)*', $gid);
+ $subnet_prefix = $tmp[0].":";
+
+ @labeled_pkeys = split(/,/, $conf{SELINUX_INFINIBAND_TEST_LABELED_PKEYS});
+ @unlabeled_pkeys = split(/,/, $conf{SELINUX_INFINIBAND_TEST_UNLABELED_PKEYS});
+
+ foreach (@unlabeled_pkeys) {
+ $result = system "runcon -t test_ibpkey_access_t $basedir/create_modify_qp $device $port $_";
+ if($result ne 0) {
+ last;
+ }
+ }
+ if (@unlabeled_pkeys) {
+ ok($result, 0);
+ } else {
+ ok(1);
+ }
+
+ foreach (@unlabeled_pkeys) {
+ $pkey_path = "/sys/class/infiniband/".$device."/ports/".$port."/pkeys/".$_;
+ open($f, $pkey_path) or die ("Couldn't open $pkey_path");
+ $pkey_val = <$f>;
+ close($f);
+
+ system "semanage ibpkey -a -t test_ibpkey_t -x $subnet_prefix $pkey_val";
+ $result = system "runcon -t test_ibpkey_access_t $basedir/create_modify_qp $device $port $_";
+ system "semanage ibpkey -d -t test_ibpkey_t -x $subnet_prefix $pkey_val";
+ if ($result>>8 ne 13) {
+ last;
+ }
+ }
+ if (@unlabeled_pkeys) {
+ ok($result>>8, 13);
+ } else {
+ ok(1);
+ }
+
+ foreach (@labeled_pkeys) {
+ $result = system "runcon -t test_ibpkey_access_t $basedir/create_modify_qp $device $port $_";
+ if ($result>>8 ne 13) {
+ last;
+ }
+ }
+ if (@labeled_pkeys) {
+ ok($result>>8, 13);
+ } else {
+ ok(1);
+ }
+} else {
+ ok(1);
+ ok(1);
+ ok(1);
+}
+exit;