Message ID | 20191112171557.3067-1-richard_c_haines@btinternet.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [V2] selinux-testsuite: Add key_socket tests | expand |
On 11/12/19 12:15 PM, Richard Haines wrote: > Test relevant key management socket permissions. > > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> > --- > V2 Change: Rework error handling > > defconfig | 4 ++ > policy/Makefile | 4 ++ > policy/test_key_socket.te | 75 ++++++++++++++++++++ > tests/Makefile | 4 ++ > tests/key_socket/.gitignore | 1 + > tests/key_socket/Makefile | 7 ++ > tests/key_socket/key_sock.c | 137 ++++++++++++++++++++++++++++++++++++ > tests/key_socket/test | 45 ++++++++++++ > 8 files changed, 277 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..5c36c72 > --- /dev/null > +++ b/policy/test_key_socket.te > @@ -0,0 +1,75 @@ > +# > +############## 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..29beb0e > --- /dev/null > +++ b/tests/key_socket/key_sock.c > @@ -0,0 +1,137 @@ > +#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); > + > + free(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)); > + close(sock); > + exit(-1); > + } > + > + 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)); > + close(sock); > + exit(errno); /* Return errno to test if EACCES */ > + } > + > + 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)); > + close(sock); > + exit(errno); /* Return errno to test if EACCES */ > + } > + > + 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); > + close(sock); > + exit(-1); > + } > + > + 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); > + } > + > + close(sock); > + return 0; > +} > diff --git a/tests/key_socket/test b/tests/key_socket/test > new file mode 100755 > index 0000000..a13327f > --- /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 management key_socket\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 } - EACCES > +$result = system "runcon -t test_key_sock_no_write_t $basedir/key_sock $v 2>&1"; > +ok( $result >> 8 eq 13 ); > + > +# Deny key_socket { read } - EACCES > +$result = system "runcon -t test_key_sock_no_read_t $basedir/key_sock $v 2>&1"; > +ok( $result >> 8 eq 13 ); > + > +exit; >
On 11/14/19 9:24 AM, Stephen Smalley wrote: > On 11/12/19 12:15 PM, Richard Haines wrote: >> Test relevant key management socket permissions. >> >> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com> > > Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Sorry, on second thought I had a question below. <snip> >> diff --git a/policy/test_key_socket.te b/policy/test_key_socket.te >> new file mode 100644 >> index 0000000..5c36c72 >> --- /dev/null >> +++ b/policy/test_key_socket.te >> @@ -0,0 +1,75 @@ >> +# >> +############## 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 }; Why was the above rule on rawip_socket necessary (and likewise for the other domains)? >> +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 };
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..5c36c72 --- /dev/null +++ b/policy/test_key_socket.te @@ -0,0 +1,75 @@ +# +############## 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..29beb0e --- /dev/null +++ b/tests/key_socket/key_sock.c @@ -0,0 +1,137 @@ +#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); + + free(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)); + close(sock); + exit(-1); + } + + 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)); + close(sock); + exit(errno); /* Return errno to test if EACCES */ + } + + 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)); + close(sock); + exit(errno); /* Return errno to test if EACCES */ + } + + 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); + close(sock); + exit(-1); + } + + 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); + } + + close(sock); + return 0; +} diff --git a/tests/key_socket/test b/tests/key_socket/test new file mode 100755 index 0000000..a13327f --- /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 management key_socket\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 } - EACCES +$result = system "runcon -t test_key_sock_no_write_t $basedir/key_sock $v 2>&1"; +ok( $result >> 8 eq 13 ); + +# Deny key_socket { read } - EACCES +$result = system "runcon -t test_key_sock_no_read_t $basedir/key_sock $v 2>&1"; +ok( $result >> 8 eq 13 ); + +exit;
Test relevant key management socket permissions. Signed-off-by: Richard Haines <richard_c_haines@btinternet.com> --- V2 Change: Rework error handling defconfig | 4 ++ policy/Makefile | 4 ++ policy/test_key_socket.te | 75 ++++++++++++++++++++ tests/Makefile | 4 ++ tests/key_socket/.gitignore | 1 + tests/key_socket/Makefile | 7 ++ tests/key_socket/key_sock.c | 137 ++++++++++++++++++++++++++++++++++++ tests/key_socket/test | 45 ++++++++++++ 8 files changed, 277 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