From: Stephen Smalley <sds@tycho.nsa.gov>
To: Richard Haines <richard_c_haines@btinternet.com>,
selinux@vger.kernel.org, paul@paul-moore.com
Subject: Re: [PATCH V5 3/3] selinux-testsuite: Add BPF support to binder test
Date: Thu, 19 Sep 2019 16:15:31 -0400 [thread overview]
Message-ID: <03c9d67b-19e1-ce1a-1ed3-40f11ece482e@tycho.nsa.gov> (raw)
In-Reply-To: <20190919174655.17348-4-richard_c_haines@btinternet.com>
On 9/19/19 1:46 PM, Richard Haines wrote:
> Add BPF map & prog functions to test binder security_binder_transfer_file()
Thanks, all three applied.
>
> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> ---
> policy/Makefile | 2 +-
> policy/test_binder_bpf.te | 73 ++++++++++++++++++++
> tests/binder/Makefile | 5 ++
> tests/binder/binder_common.c | 10 +--
> tests/binder/binder_common.h | 17 ++++-
> tests/binder/client.c | 28 ++++++--
> tests/binder/manager.c | 2 +-
> tests/binder/service_provider.c | 118 ++++++++++++++++++++++++--------
> tests/bpf/Makefile | 2 +-
> tests/bpf/test | 84 ++++++++++++++++++++++-
> 10 files changed, 296 insertions(+), 45 deletions(-)
> create mode 100644 policy/test_binder_bpf.te
>
> diff --git a/policy/Makefile b/policy/Makefile
> index 4ca5486..d72eb62 100644
> --- a/policy/Makefile
> +++ b/policy/Makefile
> @@ -72,7 +72,7 @@ TARGETS += test_sctp.te
> endif
>
> ifeq ($(shell grep -q bpf $(POLDEV)/include/support/all_perms.spt && echo true),true)
> -TARGETS += test_bpf.te test_fdreceive_bpf.te
> +TARGETS += test_bpf.te test_fdreceive_bpf.te test_binder_bpf.te
> endif
>
> ifeq (x$(DISTRO),$(filter x$(DISTRO),xRHEL4 xRHEL5 xRHEL6))
> diff --git a/policy/test_binder_bpf.te b/policy/test_binder_bpf.te
> new file mode 100644
> index 0000000..c545846
> --- /dev/null
> +++ b/policy/test_binder_bpf.te
> @@ -0,0 +1,73 @@
> +####### Policy for testing BPF file descriptor transfers via binder #########
> +
> +attribute binderbpfdomain;
> +
> +#
> +################################## Manager ##################################
> +#
> +type test_binder_bpf_mgr_t;
> +domain_type(test_binder_bpf_mgr_t)
> +unconfined_runs_test(test_binder_bpf_mgr_t)
> +typeattribute test_binder_bpf_mgr_t testdomain;
> +typeattribute test_binder_bpf_mgr_t binderdomain;
> +allow test_binder_bpf_mgr_t test_binder_bpf_client_t:binder { transfer };
> +allow test_binder_bpf_mgr_t test_binder_client_no_bpf_perm_t:binder { transfer };
> +allow test_binder_bpf_mgr_t device_t:chr_file { ioctl open read write };
> +allow_map(test_binder_bpf_mgr_t, device_t, chr_file)
> +allow test_binder_bpf_mgr_t self:binder { set_context_mgr };
> +# For writing to flag file:
> +allow test_binder_bpf_mgr_t test_file_t:fifo_file { rw_file_perms };
> +
> +#
> +########################### Service Provider ################################
> +#
> +type test_binder_bpf_provider_t;
> +domain_type(test_binder_bpf_provider_t)
> +unconfined_runs_test(test_binder_bpf_provider_t)
> +typeattribute test_binder_bpf_provider_t testdomain;
> +typeattribute test_binder_bpf_provider_t binderbpfdomain;
> +allow test_binder_bpf_provider_t test_binder_bpf_mgr_t:binder { call transfer };
> +allow test_binder_bpf_provider_t device_t:chr_file { ioctl open read write };
> +allow_map(test_binder_bpf_provider_t, device_t, chr_file)
> +# For writing to flag file:
> +allow test_binder_bpf_provider_t test_file_t:fifo_file { rw_file_perms };
> +# For testing BPF map fd transfer:
> +allow test_binder_bpf_provider_t self:bpf { map_create map_read map_write prog_load prog_run };
> +allow test_binder_bpf_provider_t self:capability { sys_resource };
> +allow test_binder_bpf_provider_t self:process { setrlimit };
> +
> +#
> +################################# Client ####################################
> +#
> +type test_binder_bpf_client_t;
> +domain_type(test_binder_bpf_client_t)
> +unconfined_runs_test(test_binder_bpf_client_t)
> +typeattribute test_binder_bpf_client_t testdomain;
> +typeattribute test_binder_bpf_client_t binderbpfdomain;
> +allow test_binder_bpf_client_t test_binder_bpf_provider_t:binder { call impersonate };
> +allow test_binder_bpf_client_t test_binder_bpf_mgr_t:binder { call };
> +allow test_binder_bpf_client_t test_binder_bpf_provider_t:fd { use };
> +allow test_binder_bpf_client_t device_t:chr_file { getattr ioctl open read write };
> +allow_map(test_binder_bpf_client_t, device_t, chr_file)
> +# For testing BPF map fd transfer:
> +allow test_binder_bpf_client_t test_binder_bpf_provider_t:bpf { map_read map_write prog_load prog_run };
> +
> +#
> +######################## Client no BPF perms #############################
> +#
> +type test_binder_client_no_bpf_perm_t;
> +domain_type(test_binder_client_no_bpf_perm_t)
> +unconfined_runs_test(test_binder_client_no_bpf_perm_t)
> +typeattribute test_binder_client_no_bpf_perm_t testdomain;
> +typeattribute test_binder_client_no_bpf_perm_t binderbpfdomain;
> +allow test_binder_client_no_bpf_perm_t test_binder_bpf_provider_t:binder { call impersonate };
> +allow test_binder_client_no_bpf_perm_t test_binder_bpf_mgr_t:binder { call };
> +allow test_binder_client_no_bpf_perm_t test_binder_bpf_provider_t:fd { use };
> +allow test_binder_client_no_bpf_perm_t device_t:chr_file { getattr ioctl open read write };
> +allow_map(test_binder_client_no_bpf_perm_t, device_t, chr_file)
> +
> +#
> +########### Allow these domains to be entered from sysadm domain ############
> +#
> +miscfiles_domain_entry_test_files(binderbpfdomain)
> +userdom_sysadm_entry_spec_domtrans_to(binderbpfdomain)
> diff --git a/tests/binder/Makefile b/tests/binder/Makefile
> index 32f9a83..e78ad16 100644
> --- a/tests/binder/Makefile
> +++ b/tests/binder/Makefile
> @@ -10,6 +10,11 @@ CFLAGS += -DHAVE_BINDERFS
> TARGETS += check_binderfs
> endif
>
> +ifneq (,$(findstring -DHAVE_BPF,$(CFLAGS)))
> + DEPS += ../bpf/bpf_common.c ../bpf/bpf_common.h
> + LDLIBS += -lbpf
> +endif
> +
> all: $(TARGETS)
>
> clean:
> diff --git a/tests/binder/binder_common.c b/tests/binder/binder_common.c
> index a240453..224238b 100644
> --- a/tests/binder/binder_common.c
> +++ b/tests/binder/binder_common.c
> @@ -3,13 +3,15 @@
> * the raw ioctl commands to test the SELinux binder permissions:
> * set_context_mgr, call, transfer, impersonate.
> *
> + * If configured, the BPF permissions are also tested.
> + *
> * Using binder test policy the following will be validated:
> * security_binder_set_context_mgr() binder { set_context_mgr }
> * security_binder_transaction() binder { call impersonate }
> * security_binder_transfer_binder() binder { transfer }
> * security_binder_transfer_file() fd { use }
> - *
> - * TODO security_binder_transfer_file() uses BPF if configured in kernel.
> + * bpf { map_create map_read map_write };
> + * bpf { prog_load prog_run };
> */
>
> #include "binder_common.h"
> @@ -67,8 +69,8 @@ void print_trans_data(const struct binder_transaction_data *txn_in)
> case TEST_SERVICE_GET:
> printf("\tcode: TEST_SERVICE_GET\n");
> break;
> - case TEST_SERVICE_SEND_CLIENT_SP_FD:
> - printf("\tcode: TEST_SERVICE_SEND_CLIENT_SP_FD\n");
> + case TEST_SERVICE_SEND_FD:
> + printf("\tcode: TEST_SERVICE_SEND_FD\n");
> break;
> default:
> printf("Unknown binder_transaction_data->code: %x\n",
> diff --git a/tests/binder/binder_common.h b/tests/binder/binder_common.h
> index bcf9e0c..30edc75 100644
> --- a/tests/binder/binder_common.h
> +++ b/tests/binder/binder_common.h
> @@ -15,6 +15,9 @@
> #if HAVE_BINDERFS
> #include <linux/android/binderfs.h>
> #endif
> +#if HAVE_BPF
> +#include "../bpf/bpf_common.h"
> +#endif
>
> #define BINDER_DEV "/dev/binder"
> #define BINDERFS_DEV "/dev/binderfs"
> @@ -26,12 +29,20 @@
> /* These are the Binder txn->code values used by the Service Provider, Client
> * and Manager to request/retrieve a binder handle or file descriptor.
> */
> -#define TEST_SERVICE_ADD 240616 /* Sent by Service Provider */
> -#define TEST_SERVICE_GET 290317 /* Sent by Client */
> -#define TEST_SERVICE_SEND_CLIENT_SP_FD 120419 /* Sent by Client */
> +#define TEST_SERVICE_ADD 240616 /* Sent by Service Provider */
> +#define TEST_SERVICE_GET 290317 /* Sent by Client */
> +#define TEST_SERVICE_SEND_FD 311019 /* Sent by Client */
>
> bool verbose;
>
> const char *cmd_name(uint32_t cmd);
> void print_trans_data(const struct binder_transaction_data *txn_in);
> int binder_write(int fd, void *data, size_t len);
> +
> +enum {
> + BINDER_FD,
> + BPF_MAP_FD,
> + BPF_PROG_FD,
> + BPF_TEST
> +} fd_type;
> +char *fd_type_str;
> diff --git a/tests/binder/client.c b/tests/binder/client.c
> index e4e2a61..4965563 100644
> --- a/tests/binder/client.c
> +++ b/tests/binder/client.c
> @@ -6,7 +6,7 @@ static int transactions_complete;
> static void usage(char *progname)
> {
> fprintf(stderr,
> - "usage: %s [-c] [-n] [-r replies] [-v]\n"
> + "usage: %s [-c] [-n] [-r replies] [-m|-p] [-v]\n"
> "Where:\n\t"
> "-c Use the number of replies for the BR_TRANSACTION_COMPLETE"
> " count.\n\t"
> @@ -15,6 +15,8 @@ static void usage(char *progname)
> " It can be the number of BR_TRANSACTION_COMPLETE if\n\t"
> " the -c option is set or number of times to issue the\n\t"
> " ioctl - BINDER_WRITE_READ command if -c not set.\n\t"
> + "-m Service Provider sending BPF map fd.\n\t"
> + "-p Service Provider sending BPF prog fd.\n\t"
> "-v Print context and command information.\n\t"
> "\nNote: Ensure this boolean command is run when "
> "testing after a reboot:\n\t"
> @@ -67,8 +69,12 @@ static void extract_fd_and_respond(const struct binder_transaction_data *txn_in)
> }
>
> if (verbose)
> - printf("Client retrieved Service Providers fd: %d st_dev: %ld\n",
> - obj->fd, sb.st_dev);
> + printf("Client retrieved %s fd: %d st_dev: %ld\n",
> + fd_type_str, obj->fd, sb.st_dev);
> +
> + /* If testing BPF, then cannot do impersonate check */
> + if (fd_type > BINDER_FD)
> + return;
>
> memset(&writebuf, 0, sizeof(writebuf));
> memset(readbuf, 0, sizeof(readbuf));
> @@ -141,7 +147,7 @@ static void request_service_provider_fd(int fd, uint32_t handle)
> writebuf.cmd = BC_TRANSACTION;
> writebuf.txn.target.handle = handle;
> writebuf.txn.cookie = 0;
> - writebuf.txn.code = TEST_SERVICE_SEND_CLIENT_SP_FD;
> + writebuf.txn.code = TEST_SERVICE_SEND_FD;
> writebuf.txn.flags = TF_ACCEPT_FDS;
>
> writebuf.txn.data_size = 0;
> @@ -270,7 +276,7 @@ static int binder_parse(int fd, binder_uintptr_t ptr, binder_size_t size)
> if (txn->code == TEST_SERVICE_GET)
> extract_handle_and_acquire(fd, txn);
>
> - if (txn->code == TEST_SERVICE_SEND_CLIENT_SP_FD)
> + if (txn->code == TEST_SERVICE_SEND_FD)
> extract_fd_and_respond(txn);
>
> ptr += sizeof(*txn);
> @@ -313,8 +319,10 @@ int main(int argc, char **argv)
> unsigned int readbuf[32];
>
> transactions_complete = 0;
> + fd_type = BINDER_FD;
> + fd_type_str = "SP";
>
> - while ((opt = getopt(argc, argv, "cnr:v")) != -1) {
> + while ((opt = getopt(argc, argv, "cnr:vmp")) != -1) {
> switch (opt) {
> case 'c':
> use_transactions_complete = true;
> @@ -328,6 +336,14 @@ int main(int argc, char **argv)
> case 'v':
> verbose = true;
> break;
> + case 'm':
> + fd_type = BPF_MAP_FD;
> + fd_type_str = "BPF map";
> + break;
> + case 'p':
> + fd_type = BPF_PROG_FD;
> + fd_type_str = "BPF prog";
> + break;
> default:
> usage(argv[0]);
> }
> diff --git a/tests/binder/manager.c b/tests/binder/manager.c
> index 9922183..8e5f446 100644
> --- a/tests/binder/manager.c
> +++ b/tests/binder/manager.c
> @@ -91,7 +91,7 @@ static void do_service_manager(int fd, struct binder_transaction_data *txn_in)
> reply_with_handle(fd, txn_in);
>
> break;
> - case TEST_SERVICE_SEND_CLIENT_SP_FD:
> + case TEST_SERVICE_SEND_FD:
> if (verbose)
> printf("Manager Rx'ed SEND_CLIENT_YOUR_BINDER_FD for handle: %d\n",
> txn_in->target.handle);
> diff --git a/tests/binder/service_provider.c b/tests/binder/service_provider.c
> index 2873af8..56d8a43 100644
> --- a/tests/binder/service_provider.c
> +++ b/tests/binder/service_provider.c
> @@ -6,11 +6,14 @@ static int binder_parse(int fd, binder_uintptr_t ptr, binder_size_t size);
> static void usage(char *progname)
> {
> fprintf(stderr,
> - "usage: %s [-e expected_ctx] [-f file] [-n] [-v]\n"
> + "usage: %s -e expected_ctx] [-f file] [-n] [-m|-p|-t] [-v]\n"
> "Where:\n\t"
> "-e Expected security context.\n\t"
> "-f Write a line to the file when listening starts.\n\t"
> "-n Use the /dev/binderfs name service.\n\t"
> + "-m Use BPF map fd for transfer.\n\t"
> + "-p Use BPF prog fd for transfer.\n\t"
> + "-t Test if BPF enabled.\n\t"
> "-v Print context and command information.\n\t"
> "\nNote: Ensure this boolean command is run when "
> "testing after a reboot:\n\t"
> @@ -34,7 +37,7 @@ static void request_service_provider_fd(int fd,
> }
>
> if (verbose)
> - printf("Service Provider sending BC_REPLY with its FD\n");
> + printf("Service Provider sending BC_REPLY with an FD\n");
>
> memset(writebuf, 0, sizeof(writebuf));
> memset(&bwr, 0, sizeof(bwr));
> @@ -56,17 +59,47 @@ static void request_service_provider_fd(int fd,
> obj.pad_flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
> #endif
> obj.cookie = txn->cookie;
> - /* The Service Providers binder fd is used for testing as it allows
> +
> + /*
> + * The Service Providers binder fd is used for testing as it allows
> * policy to set whether the Service Provider and Client can be
> * allowed access (fd use) or not.
> * This also allows a check for the impersonate permission later as
> * the Client will use the Service Provider fd to send a transaction.
> + *
> + * If a BPF fd is required, it is generated, however it cannot be
> + * used to check the impersonate permission.
> */
> - obj.fd = fd;
> + switch (fd_type) {
> + case BINDER_FD:
> + obj.fd = fd;
> + break;
> +#if HAVE_BPF
> + case BPF_MAP_FD:
> + obj.fd = create_bpf_map();
> + if (obj.fd < 0)
> + exit(70);
> + break;
> + case BPF_PROG_FD:
> + obj.fd = create_bpf_prog();
> + if (obj.fd < 0)
> + exit(71);
> + break;
> +#else
> + case BPF_MAP_FD:
> + case BPF_PROG_FD:
> + fprintf(stderr, "BPF not supported - Service Provider\n");
> + exit(72);
> + break;
> +#endif
> + default:
> + fprintf(stderr, "Invalid fd_type: %d\n", fd_type);
> + exit(73);
> + }
>
> if (verbose)
> - printf("Service Provider handle: %d and its FD: %d\n",
> - txn->target.handle, fd);
> + printf("Service Provider handle: %d and %s FD: %d\n",
> + txn->target.handle, fd_type_str, obj.fd);
>
> txn->data_size = sizeof(obj);
> txn->data.ptr.buffer = (binder_uintptr_t)&obj;
> @@ -81,7 +114,7 @@ static void request_service_provider_fd(int fd,
> fprintf(stderr,
> "Service Provider ioctl BINDER_WRITE_READ error: %s\n",
> strerror(errno));
> - exit(70);
> + exit(74);
> }
> }
>
> @@ -119,7 +152,7 @@ static int binder_parse(int fd, binder_uintptr_t ptr, binder_size_t size)
> print_trans_data(txn);
> }
>
> - if (txn->code == TEST_SERVICE_SEND_CLIENT_SP_FD)
> + if (txn->code == TEST_SERVICE_SEND_FD)
> request_service_provider_fd(fd, txn);
>
> ptr += sizeof(*txn);
> @@ -148,8 +181,7 @@ static int binder_parse(int fd, binder_uintptr_t ptr, binder_size_t size)
> }
> }
>
> - if (txn_ctx->transaction_data.code ==
> - TEST_SERVICE_SEND_CLIENT_SP_FD)
> + if (txn_ctx->transaction_data.code == TEST_SERVICE_SEND_FD)
> request_service_provider_fd(fd,
> &txn_ctx->transaction_data);
>
> @@ -209,8 +241,10 @@ int main(int argc, char **argv)
> unsigned int readbuf[32];
>
> expected_ctx = NULL;
> + fd_type = BINDER_FD;
> + fd_type_str = "SP";
>
> - while ((opt = getopt(argc, argv, "e:f:nv")) != -1) {
> + while ((opt = getopt(argc, argv, "e:f:nvmpt")) != -1) {
> switch (opt) {
> case 'e':
> expected_ctx = optarg;
> @@ -224,11 +258,37 @@ int main(int argc, char **argv)
> case 'v':
> verbose = true;
> break;
> + case 'm':
> + fd_type = BPF_MAP_FD;
> + fd_type_str = "BPF map";
> + break;
> + case 'p':
> + fd_type = BPF_PROG_FD;
> + fd_type_str = "BPF prog";
> + break;
> + case 't':
> + fd_type = BPF_TEST;
> + break;
> default:
> usage(argv[0]);
> }
> }
>
> +
> +#if HAVE_BPF
> + if (fd_type == BPF_TEST)
> + exit(0);
> +
> + /* If BPF enabed, then need to set limits */
> + if (fd_type == BPF_MAP_FD || fd_type == BPF_PROG_FD)
> + bpf_setrlimit();
> +#else
> + if (fd_type == BPF_TEST) {
> + fprintf(stderr, "BPF not supported\n");
> + exit(-1);
> + }
> +#endif
> +
> /* Get our context and pid */
> result = getcon(&context);
> if (result < 0) {
> @@ -267,19 +327,6 @@ int main(int argc, char **argv)
> exit(63);
> }
>
> - if (flag_file) {
> - flag_fd = fopen(flag_file, "w");
> - if (!flag_fd) {
> - fprintf(stderr,
> - "Service Provider failed to open %s: %s\n",
> - flag_file, strerror(errno));
> - result = 64;
> - goto brexit;
> - }
> - fprintf(flag_fd, "listening\n");
> - fclose(flag_fd);
> - }
> -
> memset(&writebuf, 0, sizeof(writebuf));
> memset(&obj, 0, sizeof(obj));
> memset(readbuf, 0, sizeof(readbuf));
> @@ -322,7 +369,7 @@ int main(int argc, char **argv)
> fprintf(stderr,
> "Service Provider ioctl BINDER_WRITE_READ error: %s\n",
> strerror(errno));
> - result = 65;
> + result = 64;
> goto brexit;
> }
>
> @@ -338,7 +385,7 @@ int main(int argc, char **argv)
> cmd == BR_DEAD_BINDER) {
> fprintf(stderr, "Service Provider %s() failing command %s, exiting.\n",
> __func__, cmd_name(cmd));
> - result = 66;
> + result = 65;
> goto brexit;
> }
>
> @@ -358,10 +405,27 @@ int main(int argc, char **argv)
> fprintf(stderr,
> "Service Provider ioctl BINDER_WRITE_READ error: %s\n",
> strerror(errno));
> - result = 67;
> + result = 66;
> goto brexit;
> }
>
> + /*
> + * Ensure the Manager and Service Provider have completed the
> + * TEST_SERVICE_ADD sequence before the Client is allowed to start.
> + */
> + if (flag_file) {
> + flag_fd = fopen(flag_file, "w");
> + if (!flag_fd) {
> + fprintf(stderr,
> + "Service Provider failed to open %s: %s\n",
> + flag_file, strerror(errno));
> + result = 67;
> + goto brexit;
> + }
> + fprintf(flag_fd, "listening\n");
> + fclose(flag_fd);
> + }
> +
> while (true) {
> memset(readbuf, 0, sizeof(readbuf));
> bwr.read_size = sizeof(readbuf);
> diff --git a/tests/bpf/Makefile b/tests/bpf/Makefile
> index 3513179..6fb230d 100644
> --- a/tests/bpf/Makefile
> +++ b/tests/bpf/Makefile
> @@ -5,7 +5,7 @@ LDLIBS += -lselinux -lbpf
> # export so that BPF_ENABLED entries get built correctly on local build
> export CFLAGS += -DHAVE_BPF
>
> -BPF_ENABLED = ../fdreceive
> +BPF_ENABLED = ../fdreceive ../binder
>
> all: $(TARGETS)
> @set -e; for i in $(BPF_ENABLED); do $(MAKE) -C $$i all ; done
> diff --git a/tests/bpf/test b/tests/bpf/test
> index b49918d..4c768be 100755
> --- a/tests/bpf/test
> +++ b/tests/bpf/test
> @@ -4,11 +4,14 @@ use Test::More;
> BEGIN {
> $basedir = $0;
> $basedir =~ s|(.*)/[^/]*|$1|;
> - $fdr_basedir = "$basedir/../fdreceive/";
> + $fdr_basedir = "$basedir/../fdreceive/";
> + $binder_basedir = "$basedir/../binder/";
>
> $test_bpf_count = 7;
> $test_fdreceive_count = 4;
>
> + $test_count = $test_bpf_count + $test_fdreceive_count;
> +
> # allow info to be shown during tests
> $v = $ARGV[0];
> if ($v) {
> @@ -20,7 +23,15 @@ BEGIN {
> $v = " ";
> }
>
> - plan tests => $test_bpf_count + $test_fdreceive_count;
> + # Test if Binder is supported
> + $test_binder = 0;
> + $result = system("$binder_basedir/check_binder $v 2>/dev/null");
> + if ( $result >> 8 eq 0 ) {
> + $test_binder = 1;
> + $test_count += 4;
> + }
> +
> + plan tests => $test_count;
> }
>
> #
> @@ -104,4 +115,73 @@ kill KILL, $pid;
> # Clean up.
> system "rm -rf $basedir/test_sock $basedir/flag";
>
> +#
> +################ BPF Tests for binder #######################
> +#
> +sub service_start {
> + my ( $service, $runcon_args, $args ) = @_;
> + my $pid;
> + my $flag = $service . "_flag";
> +
> + system("mkfifo $basedir/$flag");
> +
> + if ( ( $pid = fork() ) == 0 ) {
> + exec
> +"runcon $runcon_args $binder_basedir/$service -f $basedir/$flag $args";
> + }
> +
> + # Wait for it to initialize.
> + system("read -t 5 <>$basedir/$flag");
> + return $pid;
> +}
> +
> +sub service_end {
> + my ( $service, $pid ) = @_;
> + my $flag = $service . "_flag";
> +
> + kill KILL, $pid;
> + waitpid $pid, 0;
> + system("rm -f $basedir/$flag");
> +}
> +
> +if ($test_binder) {
> + ### Test BPF map fd on transfer ##################
> + $sm_pid = service_start( "manager", "-t test_binder_bpf_mgr_t", "$v" );
> + $sp_pid =
> + service_start( "service_provider", "-t test_binder_bpf_provider_t",
> + "-m $v" );
> +
> + # Verify that the BPF map fd can be transferred.
> + $result =
> + system
> + "runcon -t test_binder_bpf_client_t $binder_basedir/client $v -m -r 1";
> + ok( $result eq 0 );
> +
> + # Verify BPF no map perms.
> + $result = system
> +"runcon -t test_binder_client_no_bpf_perm_t $binder_basedir/client $v -m -r 2 2>&1";
> + ok( $result >> 8 eq 141 );
> +
> + ### Test BPF prog fd on transfer ##################
> + service_end( "service_provider", $sp_pid );
> + $sp_pid =
> + service_start( "service_provider", "-t test_binder_bpf_provider_t",
> + "-p $v" );
> +
> + # Verify that the BPF prog fd can be transferred.
> + $result =
> + system
> + "runcon -t test_binder_bpf_client_t $binder_basedir/client $v -p -r 1";
> + ok( $result eq 0 );
> +
> + # Verify BPF no prog perms.
> + $result = system
> +"runcon -t test_binder_client_no_bpf_perm_t $binder_basedir/client $v -p -r 2 2>&1";
> + ok( $result >> 8 eq 141 );
> +
> + # Kill the service provider & manager.
> + service_end( "service_provider", $sp_pid );
> + service_end( "manager", $sm_pid );
> +}
> +
> exit;
>
prev parent reply other threads:[~2019-09-19 20:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-19 17:46 [PATCH V5 0/3] selinux-testsuite: Add BPF tests Richard Haines
2019-09-19 17:46 ` [PATCH V5 1/3] " Richard Haines
2019-09-19 17:46 ` [PATCH V5 2/3] selinux-testsuite: Add BPF support to fdreceive test Richard Haines
2019-09-19 17:46 ` [PATCH V5 3/3] selinux-testsuite: Add BPF support to binder test Richard Haines
2019-09-19 20:15 ` Stephen Smalley [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=03c9d67b-19e1-ce1a-1ed3-40f11ece482e@tycho.nsa.gov \
--to=sds@tycho.nsa.gov \
--cc=paul@paul-moore.com \
--cc=richard_c_haines@btinternet.com \
--cc=selinux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).