From: Daniel Jurgens <danielj@xxxxxxxxxxxx> 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@xxxxxxxxxxxx> --- 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 --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; -- 2.12.2