@@ -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
@@ -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
new file mode 100644
@@ -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)
@@ -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,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);
+}
new file mode 100644
@@ -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
new file mode 100644
@@ -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;