From: Konrad Lipinski Date: Wed, 11 Sep 2019 13:42:10 +0000 (+0200) Subject: kdbus: test suite changed to common format X-Git-Tag: accepted/tizen/unified/20210119.130216~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2c0f308e6d963987fcb4e5754f504028d4511629;p=platform%2Fkernel%2Flinux-rpi.git kdbus: test suite changed to common format This commit adapts the kdbus test suite to use with dbus-integration-tests. Change-Id: Ifee21253f4e3c732b27517a0c566d4b9a569d5af Signed-off-by: Adrian Szyndela Signed-off-by: Łukasz Stelmach --- diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 02d4b86..772cc31 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -19,9 +19,9 @@ TARGETS += intel_pstate TARGETS += ipc TARGETS += ir TARGETS += kcmp +TARGETS += kdbus TARGETS += kexec TARGETS += kvm -#TARGETS += kdbus TARGETS += lib TARGETS += livepatch TARGETS += membarrier diff --git a/tools/testing/selftests/kdbus/.gitignore b/tools/testing/selftests/kdbus/.gitignore new file mode 100644 index 0000000..d3ef42f --- /dev/null +++ b/tools/testing/selftests/kdbus/.gitignore @@ -0,0 +1 @@ +kdbus-test diff --git a/tools/testing/selftests/kdbus/Makefile b/tools/testing/selftests/kdbus/Makefile index 0a5afe3..f60619c 100644 --- a/tools/testing/selftests/kdbus/Makefile +++ b/tools/testing/selftests/kdbus/Makefile @@ -1,17 +1,21 @@ CFLAGS += -I../../../../usr/include/ CFLAGS += -I../../../../samples/kdbus/ -CFLAGS += -I../../../../include/uapi/ CFLAGS += -std=gnu99 CFLAGS += -DKBUILD_MODNAME=\"kdbus\" -D_GNU_SOURCE -LDLIBS = -pthread -lcap -lm +LDFLAGS = -pthread -lcap -lm -OBJS= \ +.PHONY: all clean + +include ../lib.mk + +TEST_CUSTOM_PROGS := $(OUTPUT)/kdbus-test +all: $(TEST_CUSTOM_PROGS) + +OBJS = \ kdbus-enum.o \ kdbus-util.o \ kdbus-test.o \ - kdbus-test.o \ test-activator.o \ - test-attach-flags.o \ test-benchmark.o \ test-bus.o \ test-chat.o \ @@ -28,22 +32,14 @@ OBJS= \ test-policy.o \ test-policy-ns.o \ test-policy-priv.o \ - test-send.o \ test-sync.o \ test-timeout.o +OBJS := $(patsubst %,$(OUTPUT)/%,$(OBJS)) -all: kdbus-test - -include ../lib.mk - -%.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ - -kdbus-test: $(OBJS) - $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@ +$(TEST_CUSTOM_PROGS): $(OBJS) + $(CC) -o $(TEST_CUSTOM_PROGS) $(OBJS) $(LDFLAGS) -run_tests: - ./kdbus-test --tap +$(OBJS): $(OUTPUT)/%.o: %.c + $(CC) -c $^ -o $@ $(CFLAGS) -clean: - rm -f *.o kdbus-test +EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(OBJS) diff --git a/tools/testing/selftests/kdbus/kdbus-api.h b/tools/testing/selftests/kdbus/kdbus-api.h new file mode 100644 index 0000000..4189a6a --- /dev/null +++ b/tools/testing/selftests/kdbus/kdbus-api.h @@ -0,0 +1,114 @@ +#ifndef KDBUS_API_H +#define KDBUS_API_H + +#include +#include "kdbus-util.h" + +#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) +#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) +#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) +#define KDBUS_ITEM_NEXT(item) \ + (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size)) +#define KDBUS_FOREACH(iter, first, _size) \ + for ((iter) = (first); \ + ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ + ((uint8_t *)(iter) >= (uint8_t *)(first)); \ + (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size))) + +static inline wur int kdbus_cmd_bus_make(int control_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(control_fd, KDBUS_CMD_BUS_MAKE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_endpoint_make(int bus_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(bus_fd, KDBUS_CMD_ENDPOINT_MAKE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_endpoint_update(int ep_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(ep_fd, KDBUS_CMD_ENDPOINT_UPDATE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd) +{ + int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_update(int fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(fd, KDBUS_CMD_UPDATE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_byebye(int conn_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_BYEBYE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_conn_info(int conn_fd, struct kdbus_cmd_info *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_CONN_INFO, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_bus_creator_info(int conn_fd, struct kdbus_cmd_info *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_BUS_CREATOR_INFO, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_list(int fd, struct kdbus_cmd_list *cmd) +{ + int ret = ioctl(fd, KDBUS_CMD_LIST, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_send(int conn_fd, struct kdbus_cmd_send *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_SEND, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_recv(int conn_fd, struct kdbus_cmd_recv *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_RECV, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_name_release(int conn_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_NAME_RELEASE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_match_add(int conn_fd, struct kdbus_cmd_match *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_MATCH_ADD, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline wur int kdbus_cmd_match_remove(int conn_fd, struct kdbus_cmd_match *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_MATCH_REMOVE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +#endif /* KDBUS_API_H */ diff --git a/tools/testing/selftests/kdbus/kdbus-enum.c b/tools/testing/selftests/kdbus/kdbus-enum.c index 4f1e579..4b642c6 100644 --- a/tools/testing/selftests/kdbus/kdbus-enum.c +++ b/tools/testing/selftests/kdbus/kdbus-enum.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/tools/testing/selftests/kdbus/kdbus-enum.h b/tools/testing/selftests/kdbus/kdbus-enum.h index a67cec3..ed28cca 100644 --- a/tools/testing/selftests/kdbus/kdbus-enum.h +++ b/tools/testing/selftests/kdbus/kdbus-enum.h @@ -6,6 +6,7 @@ * Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. */ + #pragma once const char *enum_CMD(long long id); diff --git a/tools/testing/selftests/kdbus/kdbus-test.c b/tools/testing/selftests/kdbus/kdbus-test.c index 356a1c7..f8f2fcc 100644 --- a/tools/testing/selftests/kdbus/kdbus-test.c +++ b/tools/testing/selftests/kdbus/kdbus-test.c @@ -25,7 +25,6 @@ enum { TEST_CREATE_BUS = 1 << 0, TEST_CREATE_CONN = 1 << 1, - TEST_CREATE_CAN_FAIL = 1 << 2, }; struct kdbus_test { @@ -33,266 +32,336 @@ struct kdbus_test { const char *desc; int (*func)(struct kdbus_test_env *env); unsigned int flags; + unsigned timeout; }; struct kdbus_test_args { bool mntns; bool pidns; bool userns; + bool no_timeout; char *uid_map; char *gid_map; int loop; int wait; int fork; int tap_output; + unsigned nTests; + char const * const *tests; char *module; char *root; - char *test; char *busname; - char *mask_param_path; }; +pthread_mutex_t global_print_lock = PTHREAD_MUTEX_INITIALIZER; + static const struct kdbus_test tests[] = { { .name = "bus-make", .desc = "bus make functions", .func = kdbus_test_bus_make, .flags = 0, + .timeout = 10, }, { .name = "hello", .desc = "the HELLO command", .func = kdbus_test_hello, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "byebye", .desc = "the BYEBYE command", .func = kdbus_test_byebye, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "chat", .desc = "a chat pattern", .func = kdbus_test_chat, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "daemon", .desc = "a simple daemon", .func = kdbus_test_daemon, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "fd-passing", .desc = "file descriptor passing", .func = kdbus_test_fd_passing, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "endpoint", .desc = "custom endpoint", .func = kdbus_test_custom_endpoint, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "monitor", .desc = "monitor functionality", .func = kdbus_test_monitor, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "name-basics", .desc = "basic name registry functions", .func = kdbus_test_name_basic, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "name-conflict", .desc = "name registry conflict details", .func = kdbus_test_name_conflict, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "name-queue", .desc = "queuing of names", .func = kdbus_test_name_queue, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, + }, + { + .name = "name-takeover", + .desc = "takeover of names", + .func = kdbus_test_name_takeover, + .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "message-basic", .desc = "basic message handling", .func = kdbus_test_message_basic, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "message-prio", .desc = "handling of messages with priority", .func = kdbus_test_message_prio, .flags = TEST_CREATE_BUS, + .timeout = 10, + }, + { + .name = "activator-quota", + .desc = "activator message quotas are enforced", + .func = kdbus_test_activator_quota, + .flags = TEST_CREATE_BUS, + .timeout = 20, }, { .name = "message-quota", .desc = "message quotas are enforced", .func = kdbus_test_message_quota, .flags = TEST_CREATE_BUS, + .timeout = 20, }, { .name = "memory-access", .desc = "memory access", .func = kdbus_test_memory_access, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "timeout", .desc = "timeout", .func = kdbus_test_timeout, .flags = TEST_CREATE_BUS, - }, - { - .name = "send", - .desc = "send", - .func = kdbus_test_send, - .flags = TEST_CREATE_CONN | TEST_CREATE_CAN_FAIL, + .timeout = 10, }, { .name = "sync-byebye", .desc = "synchronous replies vs. BYEBYE", .func = kdbus_test_sync_byebye, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "sync-reply", .desc = "synchronous replies", .func = kdbus_test_sync_reply, .flags = TEST_CREATE_BUS, + .timeout = 10, + }, + { + .name = "big-meta", + .desc = "big metadata", + .func = kdbus_test_big_metadata, + .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "message-free", .desc = "freeing of memory", .func = kdbus_test_free, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "connection-info", .desc = "retrieving connection information", .func = kdbus_test_conn_info, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "connection-update", .desc = "updating connection information", .func = kdbus_test_conn_update, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "writable-pool", .desc = "verifying pools are never writable", .func = kdbus_test_writable_pool, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "policy", .desc = "policy", .func = kdbus_test_policy, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "policy-priv", .desc = "unprivileged bus access", .func = kdbus_test_policy_priv, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "policy-ns", .desc = "policy in user namespaces", .func = kdbus_test_policy_ns, .flags = TEST_CREATE_BUS, + .timeout = 10, + }, + { + .name = "metadata", + .desc = "metadata", + .func = kdbus_test_metadata, + .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, + }, + { + .name = "metadata-conn-info", + .desc = "metadata in connection-info", + .func = kdbus_test_metadata_conn_info, + .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "metadata-ns", .desc = "metadata in different namespaces", .func = kdbus_test_metadata_ns, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "match-id-add", .desc = "adding of matches by id", .func = kdbus_test_match_id_add, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "match-id-remove", .desc = "removing of matches by id", .func = kdbus_test_match_id_remove, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "match-replace", .desc = "replace of matches with the same cookie", .func = kdbus_test_match_replace, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "match-name-add", .desc = "adding of matches by name", .func = kdbus_test_match_name_add, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "match-name-remove", .desc = "removing of matches by name", .func = kdbus_test_match_name_remove, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "match-name-change", .desc = "matching for name changes", .func = kdbus_test_match_name_change, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "match-bloom", .desc = "matching with bloom filters", .func = kdbus_test_match_bloom, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, + }, + { + .name = "match-all", + .desc = "itemless catch-all matching", + .func = kdbus_test_match_itemless, + .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "activator", .desc = "activator connections", .func = kdbus_test_activator, .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, + .timeout = 10, }, { .name = "benchmark", .desc = "benchmark", .func = kdbus_test_benchmark, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "benchmark-nomemfds", .desc = "benchmark without using memfds", .func = kdbus_test_benchmark_nomemfds, .flags = TEST_CREATE_BUS, + .timeout = 10, }, { .name = "benchmark-uds", .desc = "benchmark comparison to UDS", .func = kdbus_test_benchmark_uds, .flags = TEST_CREATE_BUS, - }, - { - /* Last test */ - .name = "attach-flags", - .desc = "attach flags mask", - .func = kdbus_test_attach_flags, - .flags = 0, + .timeout = 10, }, }; #define N_TESTS ((int) (sizeof(tests) / sizeof(tests[0]))) -static int test_prepare_env(const struct kdbus_test *t, +static wur int test_prepare_env(const struct kdbus_test *t, const struct kdbus_test_args *args, struct kdbus_test_env *env) { @@ -301,62 +370,37 @@ static int test_prepare_env(const struct kdbus_test *t, char *n = NULL; int ret; - asprintf(&s, "%s/control", args->root); + if (0 >= asprintf(&s, "%s/control", args->root)) + fail("asprintf"); env->control_fd = open(s, O_RDWR); free(s); - ASSERT_RETURN(env->control_fd >= 0); + ASSERT_RETURN(env->control_fd,>=,0); - if (!args->busname) { - n = unique_name("test-bus"); - ASSERT_RETURN(n); - } + if (!args->busname) + ASSERT_NONZERO(n = unique_name("test-bus")); ret = kdbus_create_bus(env->control_fd, args->busname ?: n, - _KDBUS_ATTACH_ALL, _KDBUS_ATTACH_ALL, &s); free(n); - ASSERT_RETURN((ret == 0) || (t->flags & TEST_CREATE_CAN_FAIL)); + ASSERT_ZERO(ret); - asprintf(&env->buspath, "%s/%s/bus", args->root, s); + if (0 >= asprintf(&env->buspath, "%s/%s/bus", args->root, s)) + fail("asprintf"); free(s); } - if (t->flags & TEST_CREATE_CONN) { - if (!env->buspath) { - char *s = NULL; - char *n = NULL; - int ret; - - if (!args->busname) { - n = unique_name("test-bus"); - ASSERT_RETURN(n); - } - - ret = kdbus_create_bus(-1, - args->busname ?: n, - 0, - 0, &s); - free(n); - ASSERT_RETURN(ret == 0); - - asprintf(&env->buspath, "%s/%s/bus", args->root, s); - free(s); - } - ASSERT_RETURN(env->buspath); - env->conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(env->conn || (t->flags & TEST_CREATE_CAN_FAIL)); - } + if (t->flags & TEST_CREATE_CONN) + ASSERT_NONZERO(env->conn = kdbus_hello(env->buspath, 0, NULL, 0)); env->root = args->root; env->module = args->module; - env->mask_param_path = args->mask_param_path; return 0; } -void test_unprepare_env(const struct kdbus_test *t, struct kdbus_test_env *env) +static void test_unprepare_env(struct kdbus_test_env *env) { if (env->conn) { kdbus_conn_free(env->conn); @@ -364,7 +408,7 @@ void test_unprepare_env(const struct kdbus_test *t, struct kdbus_test_env *env) } if (env->control_fd >= 0) { - close(env->control_fd); + CLOSE(env->control_fd); env->control_fd = -1; } @@ -374,7 +418,7 @@ void test_unprepare_env(const struct kdbus_test *t, struct kdbus_test_env *env) } } -static int test_run(const struct kdbus_test *t, +static wur int test_run(const struct kdbus_test *t, const struct kdbus_test_args *kdbus_args, int wait) { @@ -386,55 +430,76 @@ static int test_run(const struct kdbus_test *t, return ret; if (wait > 0) { - printf("Sleeping %d seconds before running test ...\n", wait); + print("Sleeping %d seconds before running test ...\n", wait); sleep(wait); } ret = t->func(&env); - test_unprepare_env(t, &env); + test_unprepare_env(&env); return ret; } -static int test_run_forked(const struct kdbus_test *t, +static wur int test_run_forked(const struct kdbus_test *t, const struct kdbus_test_args *kdbus_args, - int wait) + int _wait) { - int ret; - pid_t pid; + int ret, result; + pid_t pid, timer_pid = 0; pid = fork(); if (pid < 0) { return TEST_ERR; } else if (pid == 0) { - ret = test_run(t, kdbus_args, wait); - _exit(ret); + ret = test_run(t, kdbus_args, _wait); + exit(ret); } - pid = waitpid(pid, &ret, 0); - if (pid <= 0) - return TEST_ERR; - else if (!WIFEXITED(ret)) - return TEST_ERR; - else - return WEXITSTATUS(ret); + if (!kdbus_args->no_timeout) { + timer_pid = fork(); + if (timer_pid < 0) { + return TEST_ERR; + } else if (timer_pid == 0) { + sleep(t->timeout); + exit(1); + } + } + + result = -1; + for (;;) { + pid_t wpid = wait(&ret); + if (wpid <= 0) + return TEST_ERR; + if (result >= 0) + break; + result = !WIFEXITED(ret) || WEXITSTATUS(ret) ? TEST_ERR + (timer_pid==wpid) : TEST_OK; + if (kdbus_args->no_timeout) + break; + kill(wpid ^ pid ^ timer_pid, SIGKILL); + } + + return result; } static void print_test_result(int ret) { switch (ret) { case TEST_OK: - printf("OK"); + print("OK"); break; case TEST_SKIP: - printf("SKIPPED"); + print("SKIPPED"); break; case TEST_ERR: - printf("ERROR"); + print("ERROR"); break; } } -static int start_all_tests(struct kdbus_test_args *kdbus_args) +static void print_res(struct kdbus_test const *t, int ret) { + printf("%s;%s\n", t->name, !ret ? "PASS" : TEST_TIME==ret ? "FAIL;TIMEOUT" : "FAIL"); +} + +static wur int start_all_tests(struct kdbus_test_args const *kdbus_args) { int ret; unsigned int fail_cnt = 0; @@ -443,7 +508,7 @@ static int start_all_tests(struct kdbus_test_args *kdbus_args) unsigned int i; if (kdbus_args->tap_output) { - printf("1..%d\n", N_TESTS); + print("1..%d\n", N_TESTS); fflush(stdout); } @@ -455,10 +520,10 @@ static int start_all_tests(struct kdbus_test_args *kdbus_args) if (!kdbus_args->tap_output) { unsigned int n; - printf("Testing %s (%s) ", t->desc, t->name); + print("Testing %s (%s) ", t->desc, t->name); for (n = 0; n < 60 - strlen(t->desc) - strlen(t->name); n++) - printf("."); - printf(" "); + print("."); + print(" "); } ret = test_run_forked(t, kdbus_args, 0); @@ -470,83 +535,87 @@ static int start_all_tests(struct kdbus_test_args *kdbus_args) skip_cnt++; break; case TEST_ERR: + case TEST_TIME: fail_cnt++; break; } if (kdbus_args->tap_output) { - printf("%sok %d - %s%s (%s)\n", - (ret == TEST_ERR) ? "not " : "", i + 1, + print("%sok %d - %s%s (%s)\n", + (ret >= TEST_ERR) ? "not " : "", i + 1, (ret == TEST_SKIP) ? "# SKIP " : "", t->desc, t->name); fflush(stdout); } else { print_test_result(ret); - printf("\n"); + print_res(t, ret); + print("\n"); } } if (kdbus_args->tap_output) - printf("Failed %d/%d tests, %.2f%% okay\n", fail_cnt, N_TESTS, + print("Failed %d/%d tests, %.2f%% okay\n", fail_cnt, N_TESTS, 100.0 - (fail_cnt * 100.0) / ((float) N_TESTS)); else - printf("\nSUMMARY: %u tests passed, %u skipped, %u failed\n", + print("\nSUMMARY: %u tests passed, %u skipped, %u failed\n", ok_cnt, skip_cnt, fail_cnt); return fail_cnt > 0 ? TEST_ERR : TEST_OK; } -static int start_one_test(struct kdbus_test_args *kdbus_args) +static wur int start_some_tests(struct kdbus_test_args const *kdbus_args) { - int i, ret; + int i, ret = TEST_ERR; bool test_found = false; + unsigned j=0, nTests = kdbus_args->nTests; + + do { + char const *tName = kdbus_args->tests[j]; + for (i = 0; i < N_TESTS; i++) { + const struct kdbus_test *t = tests + i; + + if (strcmp(t->name, tName)) + continue; + + do { + test_found = true; + if (kdbus_args->fork) + ret = test_run_forked(t, kdbus_args, + kdbus_args->wait); + else + ret = test_run(t, kdbus_args, + kdbus_args->wait); + + print("Testing %s: ", t->desc); + print_test_result(ret); + print_res(t, ret); + print("\n"); + + if (ret != TEST_OK) + break; + } while (kdbus_args->loop); + } - for (i = 0; i < N_TESTS; i++) { - const struct kdbus_test *t = tests + i; - - if (strcmp(t->name, kdbus_args->test)) - continue; - - do { - test_found = true; - if (kdbus_args->fork) - ret = test_run_forked(t, kdbus_args, - kdbus_args->wait); - else - ret = test_run(t, kdbus_args, - kdbus_args->wait); - - printf("Testing %s: ", t->desc); - print_test_result(ret); - printf("\n"); - - if (ret != TEST_OK) - break; - } while (kdbus_args->loop); - - return ret; - } - - if (!test_found) { - printf("Unknown test-id '%s'\n", kdbus_args->test); - return TEST_ERR; - } + if (!test_found) { + print("%s;UNKNOWN\n", tName); + } + } while (++j < nTests); - return TEST_OK; + return ret; } static void usage(const char *argv0) { unsigned int i, j; - printf("Usage: %s [options]\n" + print("Usage: %s [options]\n" "Options:\n" "\t-a, --tap Output test results in TAP format\n" "\t-m, --module Kdbus module name\n" "\t-x, --loop Run in a loop\n" "\t-f, --fork Fork before running a test\n" "\t-h, --help Print this help\n" - "\t-r, --root Toplevel of the kdbus hierarchy\n" + "\t-R, --root Toplevel of the kdbus hierarchy\n" "\t-t, --test Run one specific test only, in verbose mode\n" "\t-b, --bus Instead of generating a random bus name, take .\n" "\t-w, --wait Wait before actually starting test\n" @@ -557,37 +626,37 @@ static void usage(const char *argv0) "\t --gidmap gid_map GID map for user namespace\n" "\n", argv0); - printf("By default, all test are run once, and a summary is printed.\n" + print("By default, all test are run once, and a summary is printed.\n" "Available tests for --test:\n\n"); for (i = 0; i < N_TESTS; i++) { const struct kdbus_test *t = tests + i; - printf("\t%s", t->name); + print("\t%s", t->name); for (j = 0; j < 24 - strlen(t->name); j++) - printf(" "); + print(" "); - printf("Test %s\n", t->desc); + print("Test %s\n", t->desc); } - printf("\n"); - printf("Note that some tests may, if run specifically by --test, " + print("\n"); + print("Note that some tests may, if run specifically by --test, " "behave differently, and not terminate by themselves.\n"); exit(EXIT_FAILURE); } -void print_kdbus_test_args(struct kdbus_test_args *args) +void print_kdbus_test_args(struct kdbus_test_args const *args) { if (args->userns || args->pidns || args->mntns) - printf("# Starting tests in new %s%s%s namespaces%s\n", + print("# Starting tests in new %s%s%s namespaces%s\n", args->mntns ? "MOUNT " : "", args->pidns ? "PID " : "", args->userns ? "USER " : "", args->mntns ? ", kdbusfs will be remounted" : ""); else - printf("# Starting tests in the same namespaces\n"); + print("# Starting tests in the same namespaces\n"); } void print_metadata_support(void) @@ -603,15 +672,15 @@ void print_metadata_support(void) no_meta_seclabel = !config_security_is_enabled(); if (no_meta_audit | no_meta_cgroups | no_meta_seclabel) - printf("# Starting tests without %s%s%s metadata support\n", + print("# Starting tests without %s%s%s metadata support\n", no_meta_audit ? "AUDIT " : "", no_meta_cgroups ? "CGROUP " : "", no_meta_seclabel ? "SECLABEL " : ""); else - printf("# Starting tests with full metadata support\n"); + print("# Starting tests with full metadata support\n"); } -int run_tests(struct kdbus_test_args *kdbus_args) +wur int run_tests(struct kdbus_test_args const *kdbus_args) { int ret; static char control[4096]; @@ -619,13 +688,13 @@ int run_tests(struct kdbus_test_args *kdbus_args) snprintf(control, sizeof(control), "%s/control", kdbus_args->root); if (access(control, W_OK) < 0) { - printf("Unable to locate control node at '%s'.\n", + print("Unable to locate control node at '%s'.\n", control); return TEST_ERR; } - if (kdbus_args->test) { - ret = start_one_test(kdbus_args); + if (kdbus_args->nTests) { + ret = start_some_tests(kdbus_args); } else { do { ret = start_all_tests(kdbus_args); @@ -637,9 +706,9 @@ int run_tests(struct kdbus_test_args *kdbus_args) return ret; } -static void nop_handler(int sig) {} +static void nop_handler(int sig) { UNUSED(sig); } -static int test_prepare_mounts(struct kdbus_test_args *kdbus_args) +static wur int test_prepare_mounts(struct kdbus_test_args const *kdbus_args) { int ret; char kdbusfs[64] = {'\0'}; @@ -650,7 +719,7 @@ static int test_prepare_mounts(struct kdbus_test_args *kdbus_args) ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL); if (ret < 0) { ret = -errno; - printf("error mount() root: %d (%m)\n", ret); + print("error mount() root: %d (%m)\n", ret); return ret; } @@ -660,7 +729,7 @@ static int test_prepare_mounts(struct kdbus_test_args *kdbus_args) MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL); if (ret < 0) { ret = -errno; - printf("error mount() /proc : %d (%m)\n", ret); + print("error mount() /proc : %d (%m)\n", ret); return ret; } } @@ -670,14 +739,14 @@ static int test_prepare_mounts(struct kdbus_test_args *kdbus_args) MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL); if (ret < 0) { ret = -errno; - printf("error mount() %s :%d (%m)\n", kdbusfs, ret); + print("error mount() %s :%d (%m)\n", kdbusfs, ret); return ret; } return 0; } -int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) +wur int run_tests_in_namespaces(struct kdbus_test_args const *kdbus_args) { int ret; int efd = -1; @@ -692,14 +761,14 @@ int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) efd = eventfd(0, EFD_CLOEXEC); if (efd < 0) { ret = -errno; - printf("eventfd() failed: %d (%m)\n", ret); + print("eventfd() failed: %d (%m)\n", ret); return TEST_ERR; } ret = sigaction(SIGCHLD, &sa, &oldsa); if (ret < 0) { ret = -errno; - printf("sigaction() failed: %d (%m)\n", ret); + print("sigaction() failed: %d (%m)\n", ret); return TEST_ERR; } @@ -709,7 +778,7 @@ int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) (kdbus_args->mntns ? CLONE_NEWNS : 0) | (kdbus_args->pidns ? CLONE_NEWPID : 0), NULL); if (pid < 0) { - printf("clone() failed: %d (%m)\n", -errno); + print("clone() failed: %d (%m)\n", -errno); return TEST_ERR; } @@ -719,34 +788,34 @@ int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) ret = prctl(PR_SET_PDEATHSIG, SIGKILL); if (ret < 0) { ret = -errno; - printf("error prctl(): %d (%m)\n", ret); - _exit(TEST_ERR); + print("error prctl(): %d (%m)\n", ret); + exit(TEST_ERR); } /* reset sighandlers of childs */ ret = sigaction(SIGCHLD, &oldsa, NULL); if (ret < 0) { ret = -errno; - printf("sigaction() failed: %d (%m)\n", ret); - _exit(TEST_ERR); + print("sigaction() failed: %d (%m)\n", ret); + exit(TEST_ERR); } ret = eventfd_read(efd, &event_status); if (ret < 0 || event_status != 1) { - printf("error eventfd_read()\n"); - _exit(TEST_ERR); + print("error eventfd_read()\n"); + exit(TEST_ERR); } if (kdbus_args->mntns) { ret = test_prepare_mounts(kdbus_args); if (ret < 0) { - printf("error preparing mounts\n"); - _exit(TEST_ERR); + print("error preparing mounts\n"); + exit(TEST_ERR); } } ret = run_tests(kdbus_args); - _exit(ret); + exit(ret); } /* Setup userns mapping */ @@ -754,7 +823,7 @@ int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) ret = userns_map_uid_gid(pid, kdbus_args->uid_map, kdbus_args->gid_map); if (ret < 0) { - printf("error mapping uid and gid in userns\n"); + print("error mapping uid and gid in userns\n"); eventfd_write(efd, 2); return TEST_ERR; } @@ -763,14 +832,14 @@ int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) ret = eventfd_write(efd, 1); if (ret < 0) { ret = -errno; - printf("error eventfd_write(): %d (%m)\n", ret); + print("error eventfd_write(): %d (%m)\n", ret); return TEST_ERR; } rpid = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(rpid == pid, TEST_ERR); + ASSERT_RETURN_VAL(rpid,==,pid, TEST_ERR); - close(efd); + CLOSE(efd); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) return TEST_ERR; @@ -778,30 +847,28 @@ int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) return TEST_OK; } -int start_tests(struct kdbus_test_args *kdbus_args) +wur int start_tests(struct kdbus_test_args const *kdbus_args) { int ret; bool namespaces; - uint64_t kdbus_param_mask; - static char fspath[4096], parampath[4096]; namespaces = (kdbus_args->mntns || kdbus_args->pidns || kdbus_args->userns); /* for pidns we need mntns set */ if (kdbus_args->pidns && !kdbus_args->mntns) { - printf("Failed: please set both pid and mnt namesapces\n"); + print("Failed: please set both pid and mnt namesapces\n"); return TEST_ERR; } if (kdbus_args->userns) { if (!config_user_ns_is_enabled()) { - printf("User namespace not supported\n"); + print("User namespace not supported\n"); return TEST_ERR; } if (!kdbus_args->uid_map || !kdbus_args->gid_map) { - printf("Failed: please specify uid or gid mapping\n"); + print("Failed: please specify uid or gid mapping\n"); return TEST_ERR; } } @@ -809,29 +876,6 @@ int start_tests(struct kdbus_test_args *kdbus_args) print_kdbus_test_args(kdbus_args); print_metadata_support(); - /* setup kdbus paths */ - if (!kdbus_args->module) - kdbus_args->module = "kdbus"; - - if (!kdbus_args->root) { - snprintf(fspath, sizeof(fspath), "/sys/fs/%s", - kdbus_args->module); - kdbus_args->root = fspath; - } - - snprintf(parampath, sizeof(parampath), - "/sys/module/%s/parameters/attach_flags_mask", - kdbus_args->module); - kdbus_args->mask_param_path = parampath; - - ret = kdbus_sysfs_get_parameter_mask(kdbus_args->mask_param_path, - &kdbus_param_mask); - if (ret < 0) - return TEST_ERR; - - printf("# Starting tests with an attach_flags_mask=0x%llx\n", - (unsigned long long)kdbus_param_mask); - /* Start tests */ if (namespaces) ret = run_tests_in_namespaces(kdbus_args); @@ -841,10 +885,11 @@ int start_tests(struct kdbus_test_args *kdbus_args) return ret; } -int main(int argc, char *argv[]) +wur int main(int argc, char *argv[]) { int t, ret = 0; - struct kdbus_test_args *kdbus_args; + struct kdbus_test_args kdbus_args; + static char fspath[4096]; enum { ARG_MNTNS = 0x100, ARG_PIDNS, @@ -852,26 +897,22 @@ int main(int argc, char *argv[]) ARG_UIDMAP, ARG_GIDMAP, }; - char *exec = basename(argv[0]); - kdbus_args = malloc(sizeof(*kdbus_args)); - if (!kdbus_args) { - printf("unable to malloc() kdbus_args\n"); - return EXIT_FAILURE; - } - - memset(kdbus_args, 0, sizeof(*kdbus_args)); + memset(&kdbus_args, 0, sizeof(kdbus_args)); + kdbus_args.module = "kdbus"; static const struct option options[] = { { "loop", no_argument, NULL, 'x' }, { "help", no_argument, NULL, 'h' }, - { "root", required_argument, NULL, 'r' }, - { "test", required_argument, NULL, 't' }, + { "root", required_argument, NULL, 'R' }, + { "test", no_argument, NULL, 't' }, { "bus", required_argument, NULL, 'b' }, { "wait", required_argument, NULL, 'w' }, { "fork", no_argument, NULL, 'f' }, + { "list", no_argument, NULL, 'l' }, { "module", required_argument, NULL, 'm' }, { "tap", no_argument, NULL, 'a' }, + { "notimeout", no_argument, NULL, 'n' }, { "mntns", no_argument, NULL, ARG_MNTNS }, { "pidns", no_argument, NULL, ARG_PIDNS }, { "userns", no_argument, NULL, ARG_USERNS }, @@ -882,75 +923,98 @@ int main(int argc, char *argv[]) srand(time(NULL)); - if (strcmp(exec, "kdbus-test") != 0) { - kdbus_args->test = exec; - } + bool gotT = 0; - while ((t = getopt_long(argc, argv, "hxfm:r:t:b:w:a", options, NULL)) >= 0) { + while ((t = getopt_long(argc, argv, "xhtflnm:R:b:w:a:", options, NULL)) >= 0) { switch (t) { case 'x': - kdbus_args->loop = 1; + kdbus_args.loop = 1; break; case 'm': - kdbus_args->module = optarg; + kdbus_args.module = optarg; break; - case 'r': - kdbus_args->root = optarg; + case 'R': + kdbus_args.root = optarg; break; case 't': - kdbus_args->test = optarg; + gotT = 1; break; case 'b': - kdbus_args->busname = optarg; + kdbus_args.busname = optarg; break; case 'w': - kdbus_args->wait = strtol(optarg, NULL, 10); + kdbus_args.wait = strtol(optarg, NULL, 10); break; case 'f': - kdbus_args->fork = 1; + kdbus_args.fork = 1; break; case 'a': - kdbus_args->tap_output = 1; + kdbus_args.tap_output = 1; break; + case 'n': + kdbus_args.no_timeout = 1; + break; + + case 'l': + { + unsigned i = 0; + do { + const struct kdbus_test *t = &tests[i]; + printf("%s;%s\n", t->name, t->desc); + } while (++i < TABSIZE(tests)-1); + } + return 0; + case ARG_MNTNS: - kdbus_args->mntns = true; + kdbus_args.mntns = true; break; case ARG_PIDNS: - kdbus_args->pidns = true; + kdbus_args.pidns = true; break; case ARG_USERNS: - kdbus_args->userns = true; + kdbus_args.userns = true; break; case ARG_UIDMAP: - kdbus_args->uid_map = optarg; + kdbus_args.uid_map = optarg; break; case ARG_GIDMAP: - kdbus_args->gid_map = optarg; + kdbus_args.gid_map = optarg; break; - default: case 'h': usage(argv[0]); + + default:; } } - ret = start_tests(kdbus_args); + if ((kdbus_args.nTests = argc-optind)) { + kdbus_args.tests = (char const * const *)&argv[optind]; + if (1 < kdbus_args.nTests || !gotT) + kdbus_args.fork = 1; + } + + if (!kdbus_args.root) { + snprintf(fspath, sizeof(fspath), "/sys/fs/%s", + kdbus_args.module); + kdbus_args.root = fspath; + } + + ret = start_tests(&kdbus_args); if (ret == TEST_ERR) return EXIT_FAILURE; - free(kdbus_args); - return 0; } diff --git a/tools/testing/selftests/kdbus/kdbus-test.h b/tools/testing/selftests/kdbus/kdbus-test.h index 826b9f4..e0a6abc 100644 --- a/tools/testing/selftests/kdbus/kdbus-test.h +++ b/tools/testing/selftests/kdbus/kdbus-test.h @@ -1,11 +1,14 @@ #ifndef _TEST_KDBUS_H_ #define _TEST_KDBUS_H_ +#include +#include +#include "kdbus-util.h" + struct kdbus_test_env { char *buspath; const char *root; const char *module; - const char *mask_param_path; int control_fd; struct kdbus_conn *conn; }; @@ -14,73 +17,97 @@ enum { TEST_OK, TEST_SKIP, TEST_ERR, + TEST_TIME, }; -#define ASSERT_RETURN_VAL(cond, val) \ - if (!(cond)) { \ - fprintf(stderr, "Assertion '%s' failed in %s(), %s:%d\n", \ - #cond, __func__, __FILE__, __LINE__); \ - return val; \ - } +#if 0 + #define print_assert_success print +#else + #define print_assert_success(...) do {} while (0) +#endif + +#define PRINTF_FMT(...) _Generic((__VA_ARGS__),\ + bool: "%d",\ + int: "%d",\ + long: "%ld",\ + long long: "%lld",\ + unsigned: "%u",\ + unsigned long: "%lu",\ + unsigned long long: "%llu",\ + default: "%p") +#define PRINTF_ARG(...) (_Generic((__VA_ARGS__),\ + default: (__VA_ARGS__))) -#define ASSERT_EXIT_VAL(cond, val) \ - if (!(cond)) { \ - fprintf(stderr, "Assertion '%s' failed in %s(), %s:%d\n", \ - #cond, __func__, __FILE__, __LINE__); \ - _exit(val); \ - } +#define _ASSERT_REL_(val0, val0s, relop, val1, val1s, onfailure) do {\ + __auto_type const _ASSERT_RETURN_VAL_val0_ = (val0);\ + __auto_type const _ASSERT_RETURN_VAL_val1_ = (val1);\ + if (!(_ASSERT_RETURN_VAL_val0_ relop _ASSERT_RETURN_VAL_val1_)) { \ + /* must assemble format string in runtime because _Generic does not play well with string constant concatenation */\ + char _ASSERT_REL_fmt_[sizeof("[tid %u] Assertion '(")+3+sizeof("=%s) %s (")+3+sizeof("=%s)' failed in %s(), %s:%d\n")];\ + strcpy(_ASSERT_REL_fmt_, "[tid %u] Assertion '(");\ + strcat(_ASSERT_REL_fmt_, PRINTF_FMT(_ASSERT_RETURN_VAL_val0_));\ + strcat(_ASSERT_REL_fmt_, "=%s) %s (");\ + strcat(_ASSERT_REL_fmt_, PRINTF_FMT(_ASSERT_RETURN_VAL_val1_));\ + strcat(_ASSERT_REL_fmt_, "=%s)' failed in %s(), %s:%d\n");\ + print(_ASSERT_REL_fmt_, syscall(SYS_gettid), PRINTF_ARG(_ASSERT_RETURN_VAL_val0_), val0s, #relop, PRINTF_ARG(_ASSERT_RETURN_VAL_val1_), val1s, __func__, __FILE__, __LINE__);\ + onfailure;\ + }\ + else print_assert_success("Assertion '%s' SUCCEEDED in %s(), %s:%d\n", val0s " " #relop " " val1s, __func__, __FILE__, __LINE__);\ +} while (0) -#define ASSERT_BREAK(cond) \ - if (!(cond)) { \ - fprintf(stderr, "Assertion '%s' failed in %s(), %s:%d\n", \ - #cond, __func__, __FILE__, __LINE__); \ - break; \ - } +#define ASSERT_RETURN_VAL(val0, relop, val1, retval) _ASSERT_REL_(val0, #val0, relop, val1, #val1, return retval) +#define ASSERT_EXIT_VAL(val0, relop, val1, retval) _ASSERT_REL_(val0, #val0, relop, val1, #val1, exit(retval)) -#define ASSERT_RETURN(cond) \ - ASSERT_RETURN_VAL(cond, TEST_ERR) +#define ASSERT_RETURN(val0, relop, val1) _ASSERT_REL_(val0, #val0, relop, val1, #val1, return TEST_ERR) +#define ASSERT_EXIT(val0, relop, val1) _ASSERT_REL_(val0, #val0, relop, val1, #val1, exit(TEST_ERR)) -#define ASSERT_EXIT(cond) \ - ASSERT_EXIT_VAL(cond, EXIT_FAILURE) +#define ASSERT_ZERO(...) _ASSERT_REL_(((typeof((__VA_ARGS__)))0), "0", ==, (__VA_ARGS__), #__VA_ARGS__, return TEST_ERR) +#define ASSERT_NONZERO(...) _ASSERT_REL_(((typeof((__VA_ARGS__)))0), "0", !=, (__VA_ARGS__), #__VA_ARGS__, return TEST_ERR) +#define ASSERT_EXIT_ZERO(...) _ASSERT_REL_(((typeof((__VA_ARGS__)))0), "0", ==, (__VA_ARGS__), #__VA_ARGS__, exit(TEST_ERR)) +#define ASSERT_EXIT_NONZERO(...) _ASSERT_REL_(((typeof((__VA_ARGS__)))0), "0", !=, (__VA_ARGS__), #__VA_ARGS__, exit(TEST_ERR)) -int kdbus_test_activator(struct kdbus_test_env *env); -int kdbus_test_attach_flags(struct kdbus_test_env *env); -int kdbus_test_benchmark(struct kdbus_test_env *env); -int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env); -int kdbus_test_benchmark_uds(struct kdbus_test_env *env); -int kdbus_test_bus_make(struct kdbus_test_env *env); -int kdbus_test_byebye(struct kdbus_test_env *env); -int kdbus_test_chat(struct kdbus_test_env *env); -int kdbus_test_conn_info(struct kdbus_test_env *env); -int kdbus_test_conn_update(struct kdbus_test_env *env); -int kdbus_test_daemon(struct kdbus_test_env *env); -int kdbus_test_custom_endpoint(struct kdbus_test_env *env); -int kdbus_test_fd_passing(struct kdbus_test_env *env); -int kdbus_test_free(struct kdbus_test_env *env); -int kdbus_test_hello(struct kdbus_test_env *env); -int kdbus_test_match_bloom(struct kdbus_test_env *env); -int kdbus_test_match_id_add(struct kdbus_test_env *env); -int kdbus_test_match_id_remove(struct kdbus_test_env *env); -int kdbus_test_match_replace(struct kdbus_test_env *env); -int kdbus_test_match_name_add(struct kdbus_test_env *env); -int kdbus_test_match_name_change(struct kdbus_test_env *env); -int kdbus_test_match_name_remove(struct kdbus_test_env *env); -int kdbus_test_message_basic(struct kdbus_test_env *env); -int kdbus_test_message_prio(struct kdbus_test_env *env); -int kdbus_test_message_quota(struct kdbus_test_env *env); -int kdbus_test_memory_access(struct kdbus_test_env *env); -int kdbus_test_metadata_ns(struct kdbus_test_env *env); -int kdbus_test_monitor(struct kdbus_test_env *env); -int kdbus_test_name_basic(struct kdbus_test_env *env); -int kdbus_test_name_conflict(struct kdbus_test_env *env); -int kdbus_test_name_queue(struct kdbus_test_env *env); -int kdbus_test_policy(struct kdbus_test_env *env); -int kdbus_test_policy_ns(struct kdbus_test_env *env); -int kdbus_test_policy_priv(struct kdbus_test_env *env); -int kdbus_test_send(struct kdbus_test_env *env); -int kdbus_test_sync_byebye(struct kdbus_test_env *env); -int kdbus_test_sync_reply(struct kdbus_test_env *env); -int kdbus_test_timeout(struct kdbus_test_env *env); -int kdbus_test_writable_pool(struct kdbus_test_env *env); +wur int kdbus_test_activator(struct kdbus_test_env *env); +wur int kdbus_test_benchmark(struct kdbus_test_env *env); +wur int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env); +wur int kdbus_test_benchmark_uds(struct kdbus_test_env *env); +wur int kdbus_test_bus_make(struct kdbus_test_env *env); +wur int kdbus_test_byebye(struct kdbus_test_env *env); +wur int kdbus_test_chat(struct kdbus_test_env *env); +wur int kdbus_test_conn_info(struct kdbus_test_env *env); +wur int kdbus_test_conn_update(struct kdbus_test_env *env); +wur int kdbus_test_daemon(struct kdbus_test_env *env); +wur int kdbus_test_custom_endpoint(struct kdbus_test_env *env); +wur int kdbus_test_fd_passing(struct kdbus_test_env *env); +wur int kdbus_test_free(struct kdbus_test_env *env); +wur int kdbus_test_hello(struct kdbus_test_env *env); +wur int kdbus_test_match_bloom(struct kdbus_test_env *env); +wur int kdbus_test_match_itemless(struct kdbus_test_env *env); +wur int kdbus_test_match_id_add(struct kdbus_test_env *env); +wur int kdbus_test_match_id_remove(struct kdbus_test_env *env); +wur int kdbus_test_match_replace(struct kdbus_test_env *env); +wur int kdbus_test_match_name_add(struct kdbus_test_env *env); +wur int kdbus_test_match_name_change(struct kdbus_test_env *env); +wur int kdbus_test_match_name_remove(struct kdbus_test_env *env); +wur int kdbus_test_message_basic(struct kdbus_test_env *env); +wur int kdbus_test_message_prio(struct kdbus_test_env *env); +wur int kdbus_test_activator_quota(struct kdbus_test_env *env); +wur int kdbus_test_message_quota(struct kdbus_test_env *env); +wur int kdbus_test_memory_access(struct kdbus_test_env *env); +wur int kdbus_test_metadata(struct kdbus_test_env *env); +wur int kdbus_test_metadata_conn_info(struct kdbus_test_env *env); +wur int kdbus_test_metadata_ns(struct kdbus_test_env *env); +wur int kdbus_test_monitor(struct kdbus_test_env *env); +wur int kdbus_test_name_basic(struct kdbus_test_env *env); +wur int kdbus_test_name_conflict(struct kdbus_test_env *env); +wur int kdbus_test_name_queue(struct kdbus_test_env *env); +wur int kdbus_test_name_takeover(struct kdbus_test_env *env); +wur int kdbus_test_policy(struct kdbus_test_env *env); +wur int kdbus_test_policy_ns(struct kdbus_test_env *env); +wur int kdbus_test_policy_priv(struct kdbus_test_env *env); +wur int kdbus_test_sync_byebye(struct kdbus_test_env *env); +wur int kdbus_test_sync_reply(struct kdbus_test_env *env); +wur int kdbus_test_big_metadata(struct kdbus_test_env *env); +wur int kdbus_test_timeout(struct kdbus_test_env *env); +wur int kdbus_test_writable_pool(struct kdbus_test_env *env); #endif /* _TEST_KDBUS_H_ */ diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c index 6677dad..49aa4b7 100644 --- a/tools/testing/selftests/kdbus/kdbus-util.c +++ b/tools/testing/selftests/kdbus/kdbus-util.c @@ -29,7 +29,6 @@ #include #include #include -#include #ifndef __NR_memfd_create #ifdef __x86_64__ @@ -44,6 +43,7 @@ #include "kdbus-api.h" #include "kdbus-util.h" #include "kdbus-enum.h" +#include "kdbus-test.h" #ifndef F_ADD_SEALS #define F_LINUX_SPECIFIC_BASE 1024 @@ -56,9 +56,12 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ #endif +/* maximum number of well-known names per connection */ +#define KDBUS_CONN_MAX_NAMES 256 + int kdbus_util_verbose = true; -int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask) +wur int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask) { int ret; FILE *file; @@ -90,7 +93,7 @@ int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask) return 0; } -int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask) +wur int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask) { int ret; FILE *file; @@ -113,9 +116,8 @@ int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask) return ret > 0 ? 0 : ret; } -int kdbus_create_bus(int control_fd, const char *name, - uint64_t req_meta, uint64_t owner_meta, - char **path) +wur int kdbus_create_bus(int control_fd, const char *name, + uint64_t owner_meta, char **path) { struct { struct kdbus_cmd cmd; @@ -127,12 +129,12 @@ int kdbus_create_bus(int control_fd, const char *name, struct kdbus_bloom_parameter bloom; } bp; - /* required and owner metadata items */ + /* owner metadata items */ struct { uint64_t size; uint64_t type; uint64_t flags; - } attach[2]; + } attach; /* name item */ struct { @@ -141,7 +143,7 @@ int kdbus_create_bus(int control_fd, const char *name, char str[64]; } name; } bus_make; - int ret = 0; + int ret; memset(&bus_make, 0, sizeof(bus_make)); bus_make.bp.size = sizeof(bus_make.bp); @@ -152,13 +154,9 @@ int kdbus_create_bus(int control_fd, const char *name, snprintf(bus_make.name.str, sizeof(bus_make.name.str), "%u-%s", getuid(), name); - bus_make.attach[0].type = KDBUS_ITEM_ATTACH_FLAGS_RECV; - bus_make.attach[0].size = sizeof(bus_make.attach[0]); - bus_make.attach[0].flags = req_meta; - - bus_make.attach[1].type = KDBUS_ITEM_ATTACH_FLAGS_SEND; - bus_make.attach[1].size = sizeof(bus_make.attach[0]); - bus_make.attach[1].flags = owner_meta; + bus_make.attach.type = KDBUS_ITEM_ATTACH_FLAGS_SEND; + bus_make.attach.size = sizeof(bus_make.attach); + bus_make.attach.flags = owner_meta; bus_make.name.type = KDBUS_ITEM_MAKE_NAME; bus_make.name.size = KDBUS_ITEM_HEADER_SIZE + @@ -167,21 +165,16 @@ int kdbus_create_bus(int control_fd, const char *name, bus_make.cmd.flags = KDBUS_MAKE_ACCESS_WORLD; bus_make.cmd.size = sizeof(bus_make.cmd) + bus_make.bp.size + - bus_make.attach[0].size + - bus_make.attach[1].size + + bus_make.attach.size + bus_make.name.size; - if (control_fd != -1) { - kdbus_printf( - "Creating bus with name >%s< on control fd %d ...\n", - name, control_fd); + kdbus_printf("Creating bus with name >%s< on control fd %d ...\n", + name, control_fd); - ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd); - if (ret < 0) { - kdbus_printf("--- error when making bus: %d (%m)\n", - ret); - return ret; - } + ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd); + if (ret < 0) { + kdbus_printf("--- error when making bus: %d (%m)\n", ret); + return ret; } if (ret == 0 && path) @@ -190,7 +183,7 @@ int kdbus_create_bus(int control_fd, const char *name, return ret; } -struct kdbus_conn * +wur struct kdbus_conn * kdbus_hello(const char *path, uint64_t flags, const struct kdbus_item *item, size_t item_size) { @@ -247,28 +240,34 @@ kdbus_hello(const char *path, uint64_t flags, cmd_free.size = sizeof(cmd_free); cmd_free.offset = h.hello.offset; - kdbus_cmd_free(fd, &cmd_free); + ret = kdbus_cmd_free(fd, &cmd_free); + if (ret < 0 && !(flags & KDBUS_HELLO_POLICY_HOLDER && -EOPNOTSUPP == ret)) { /* free not supported for policy holders */ + print("hello: KDBUS_CMD_FREE err(%d)\n", ret); + return NULL; + } - conn = malloc(sizeof(*conn)); + conn = alloc(sizeof(*conn)); if (!conn) { - kdbus_printf("unable to malloc()!?\n"); + kdbus_printf("unable to alloc()!?\n"); return NULL; } conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); if (conn->buf == MAP_FAILED) { free(conn); - close(fd); + CLOSE(fd); kdbus_printf("--- error mmap (%m)\n"); return NULL; } conn->fd = fd; conn->id = h.hello.id; + _Static_assert((typeof(conn->attach_flags_recv))_KDBUS_ATTACH_ALL == _KDBUS_ATTACH_ALL, "kdbus_conn::attach_flags_recv too narrow for _KDBUS_ATTACH_ALL"); + conn->attach_flags_recv = _KDBUS_ATTACH_ALL; return conn; } -struct kdbus_conn * +wur struct kdbus_conn * kdbus_hello_registrar(const char *path, const char *name, const struct kdbus_policy_access *access, size_t num_access, uint64_t flags) @@ -302,7 +301,7 @@ kdbus_hello_registrar(const char *path, const char *name, return kdbus_hello(path, flags, items, size); } -struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name, +wur struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name, const struct kdbus_policy_access *access, size_t num_access) { @@ -310,7 +309,7 @@ struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name, KDBUS_HELLO_ACTIVATOR); } -bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type) +wur bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type) { const struct kdbus_item *item; @@ -321,7 +320,7 @@ bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type) return false; } -int kdbus_bus_creator_info(struct kdbus_conn *conn, +wur int kdbus_bus_creator_info(struct kdbus_conn *conn, uint64_t flags, uint64_t *offset) { @@ -343,55 +342,85 @@ int kdbus_bus_creator_info(struct kdbus_conn *conn, if (offset) *offset = cmd->offset; else - kdbus_free(conn, cmd->offset); + ret = kdbus_free(conn, cmd->offset); - return 0; + return ret; } -int kdbus_conn_info(struct kdbus_conn *conn, uint64_t id, +wur static int kdbus_info_verify(struct kdbus_info *info, unsigned attach_flags); + +wur int kdbus_conn_info(struct kdbus_conn *conn, uint64_t id, const char *name, uint64_t flags, uint64_t *offset) { struct kdbus_cmd_info *cmd; size_t size = sizeof(*cmd); + size_t full_size; struct kdbus_info *info; int ret; + /*print("call prepared 0\n");*/ + if (name) size += KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - cmd = alloca(size); - memset(cmd, 0, size); + /*print("call prepared 1\n");*/ + + full_size = KDBUS_ALIGN8(size) + 1000; + + /*print("call prepared 2\n");*/ + + cmd = malloc(full_size); + if (!cmd) + return -ENOMEM; + /*print("call prepared 3\n");*/ + memset(cmd, 0, full_size); + /*print("call prepared 4\n");*/ cmd->size = size; + /*print("call prepared 5\n");*/ cmd->attach_flags = flags; + /*print("call prepared 6\n");*/ if (name) { + /*print("call prepared 7\n");*/ cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; + /*print("call prepared 8\n");*/ cmd->items[0].type = KDBUS_ITEM_NAME; - strcpy(cmd->items[0].str, name); + /*print("call prepared 9 cmd(%p) cmd->items[0].str(%p) full_size(%u) len(%u) name(%s)\n", cmd, cmd->items[0].str, (unsigned)full_size, (unsigned)strlen(name), name);*/ + + /* tizen 3.0 strcpy reports buffer overflow for no apparent reason - memcpy doesn't */ + memcpy(cmd->items[0].str, name, strlen(name)); + /*strcpy(cmd->items[0].str, name);*/ } else { + /*print("call prepared 10\n");*/ cmd->id = id; } + /*print("call prepared 11\n");*/ + ret = kdbus_cmd_conn_info(conn->fd, cmd); if (ret < 0) { kdbus_printf("--- error when requesting info: %d (%m)\n", ret); + free(cmd); return ret; } info = (struct kdbus_info *) (conn->buf + cmd->offset); - if (info->size != cmd->info_size) { + if (KDBUS_ALIGN8(info->size) != cmd->info_size) { kdbus_printf("%s(): size mismatch: %d != %d\n", __func__, (int) info->size, (int) cmd->info_size); + free(cmd); return -EIO; } - if (offset) + if (offset) { *offset = cmd->offset; - else - kdbus_free(conn, cmd->offset); + ASSERT_ZERO(kdbus_info_verify(info, flags)); + } else + ret = kdbus_free(conn, cmd->offset); - return 0; + free(cmd); + return ret; } void kdbus_conn_free(struct kdbus_conn *conn) @@ -399,41 +428,39 @@ void kdbus_conn_free(struct kdbus_conn *conn) if (!conn) return; - if (conn->buf) - munmap(conn->buf, POOL_SIZE); + if (conn->buf && munmap(conn->buf, POOL_SIZE)) + fail("munmap(%p) err(%d)", conn->buf, errno); - if (conn->fd >= 0) - close(conn->fd); + if (conn->fd >= 0 && close(conn->fd)) + fail("close(%d) err(%d)", conn->fd, errno); free(conn); } -int sys_memfd_create(const char *name, __u64 size) +wur int sys_memfd_create(const char *name, __u64 size) { int ret, fd; - ret = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING); - if (ret < 0) - return ret; - - fd = ret; + fd = syscall(__NR_memfd_create, name, 2/*MFD_ALLOW_SEALING*/); + if (fd < 0) + return fd; ret = ftruncate(fd, size); if (ret < 0) { - close(fd); + CLOSE(fd); return ret; } return fd; } -int sys_memfd_seal_set(int fd) +wur int sys_memfd_seal_set(int fd) { return fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL); } -off_t sys_memfd_get_size(int fd, off_t *size) +wur off_t sys_memfd_get_size(int fd, off_t *size) { struct stat stat; int ret; @@ -448,7 +475,7 @@ off_t sys_memfd_get_size(int fd, off_t *size) return 0; } -static int __kdbus_msg_send(const struct kdbus_conn *conn, +static wur int __kdbus_msg_send(const struct kdbus_conn *conn, const char *name, uint64_t cookie, uint64_t flags, @@ -456,12 +483,10 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn, int64_t priority, uint64_t dst_id, uint64_t cmd_flags, - int cancel_fd, - int fds_count, - int fds[]) + int cancel_fd) { - struct kdbus_cmd_send *cmd; - struct kdbus_msg *msg; + struct kdbus_cmd_send *cmd = NULL; + struct kdbus_msg *msg = NULL; const char ref1[1024 * 128 + 3] = "0123456789_0"; const char ref2[] = "0123456789_1"; struct kdbus_item *item; @@ -470,11 +495,7 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn, int memfd = -1; int ret; - size = sizeof(*msg); - size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); - size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); - size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); - size += fds_count > 0 ? KDBUS_ITEM_SIZE(sizeof(int) * fds_count) : 0; + size = sizeof(*msg) + 3 * KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); if (dst_id == KDBUS_DST_ID_BROADCAST) size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; @@ -488,14 +509,14 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn, if (write(memfd, "kdbus memfd 1234567", 19) != 19) { ret = -errno; kdbus_printf("writing to memfd failed: %m\n"); - return ret; + goto out; } ret = sys_memfd_seal_set(memfd); if (ret < 0) { ret = -errno; kdbus_printf("memfd sealing failed: %m\n"); - return ret; + goto out; } size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); @@ -504,11 +525,11 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn, if (name) size += KDBUS_ITEM_SIZE(strlen(name) + 1); - msg = malloc(size); + msg = alloc(size); if (!msg) { ret = -errno; - kdbus_printf("unable to malloc()!?\n"); - return ret; + kdbus_printf("unable to alloc()!?\n"); + goto out; } if (dst_id == KDBUS_DST_ID_BROADCAST) @@ -526,7 +547,7 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn, if (timeout) { ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now); if (ret < 0) - return ret; + goto out; msg->timeout_ns = now.tv_sec * 1000000000ULL + now.tv_nsec + timeout; @@ -572,23 +593,17 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn, } item = KDBUS_ITEM_NEXT(item); - if (fds_count > 0) { - item->type = KDBUS_ITEM_FDS; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(int) * fds_count; - memcpy(&item->fds, fds, sizeof(int) * fds_count); - item = KDBUS_ITEM_NEXT(item); - } - size = sizeof(*cmd); if (cancel_fd != -1) size += KDBUS_ITEM_SIZE(sizeof(cancel_fd)); - cmd = malloc(size); + cmd = alloc(size); if (!cmd) { ret = -errno; - kdbus_printf("unable to malloc(%ld)!?\n", (long)size); - return ret; + kdbus_printf("unable to alloc()!?\n"); + goto out; } + cmd->size = size; cmd->flags = cmd_flags; cmd->msg_address = (uintptr_t)msg; @@ -602,54 +617,54 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn, item = KDBUS_ITEM_NEXT(item); } - ret = kdbus_cmd_send(conn->fd, cmd); - if (memfd >= 0) - close(memfd); - if (ret < 0) { kdbus_printf("error sending message: %d (%m)\n", ret); - return ret; + goto out; } if (cmd_flags & KDBUS_SEND_SYNC_REPLY) { struct kdbus_msg *reply; + int dumpret; kdbus_printf("SYNC REPLY @offset %llu:\n", cmd->reply.offset); reply = (struct kdbus_msg *)(conn->buf + cmd->reply.offset); - kdbus_msg_dump(conn, reply); + dumpret = kdbus_msg_dump(reply); kdbus_msg_free(reply); ret = kdbus_free(conn, cmd->reply.offset); - if (ret < 0) - return ret; + if (!ret) + ret = dumpret; } +out: free(msg); free(cmd); - return 0; + if (memfd >= 0) + CLOSE(memfd); + + return ret < 0 ? ret : 0; } -int kdbus_msg_send(const struct kdbus_conn *conn, const char *name, +wur int kdbus_msg_send(const struct kdbus_conn *conn, const char *name, uint64_t cookie, uint64_t flags, uint64_t timeout, - int64_t priority, uint64_t dst_id, int fds_count, int fds[]) + int64_t priority, uint64_t dst_id) { return __kdbus_msg_send(conn, name, cookie, flags, timeout, priority, - dst_id, 0, -1, fds_count, fds); + dst_id, 0, -1); } -int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name, +wur int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name, uint64_t cookie, uint64_t flags, uint64_t timeout, int64_t priority, uint64_t dst_id, int cancel_fd) { return __kdbus_msg_send(conn, name, cookie, flags, timeout, priority, - dst_id, KDBUS_SEND_SYNC_REPLY, cancel_fd, - 0, NULL); + dst_id, KDBUS_SEND_SYNC_REPLY, cancel_fd); } -int kdbus_msg_send_reply(const struct kdbus_conn *conn, +wur int kdbus_msg_send_reply(const struct kdbus_conn *conn, uint64_t reply_cookie, uint64_t dst_id) { @@ -663,9 +678,9 @@ int kdbus_msg_send_reply(const struct kdbus_conn *conn, size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); - msg = malloc(size); + msg = alloc(size); if (!msg) { - kdbus_printf("unable to malloc()!?\n"); + kdbus_printf("unable to alloc()!?\n"); return -ENOMEM; } @@ -696,7 +711,7 @@ int kdbus_msg_send_reply(const struct kdbus_conn *conn, return ret; } -static char *msg_id(uint64_t id, char *buf) +static wur char *msg_id(uint64_t id, char *buf) { if (id == 0) return "KERNEL"; @@ -706,8 +721,7 @@ static char *msg_id(uint64_t id, char *buf) return buf; } -int kdbus_msg_dump(const struct kdbus_conn *conn, const struct kdbus_msg *msg) -{ +wur int kdbus_msg_dump(const struct kdbus_msg *msg) { const struct kdbus_item *item = msg->items; char buf_src[32]; char buf_dst[32]; @@ -720,8 +734,9 @@ int kdbus_msg_dump(const struct kdbus_conn *conn, const struct kdbus_msg *msg) else cookie_reply = msg->cookie_reply; - kdbus_printf("MESSAGE: %s (%llu bytes) flags=0x%08llx, %s → %s, " + kdbus_printf("MESSAGE(%p): %s (%llu bytes) flags=0x%08llx, %s → %s, " "cookie=%llu, timeout=%llu cookie_reply=%llu priority=%lli\n", + msg, enum_PAYLOAD(msg->payload_type), (unsigned long long)msg->size, (unsigned long long)msg->flags, msg_id(msg->src_id, buf_src), msg_id(msg->dst_id, buf_dst), @@ -732,8 +747,7 @@ int kdbus_msg_dump(const struct kdbus_conn *conn, const struct kdbus_msg *msg) if (item->size < KDBUS_ITEM_HEADER_SIZE) { kdbus_printf(" +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size); - ret = -EINVAL; - break; + return -EINVAL; } switch (item->type) { @@ -783,10 +797,10 @@ int kdbus_msg_dump(const struct kdbus_conn *conn, const struct kdbus_msg *msg) break; } - kdbus_printf(" +%s (%llu bytes) fd=%i size=%llu filesize=%llu '%s'\n", + kdbus_printf(" +%s (%llu bytes) fd=%i size=%llu filesize=%llu '0x%llx'\n", enum_MSG(item->type), item->size, item->memfd.fd, (unsigned long long)item->memfd.size, - (unsigned long long)size, buf); + (unsigned long long)size, (unsigned long long)(size >= 8 ? *(unsigned long long *)buf : size >= 4 ? *(unsigned *)buf : *buf)); munmap(buf, item->memfd.size); break; } @@ -966,21 +980,218 @@ void kdbus_msg_free(struct kdbus_msg *msg) switch (item->type) { /* close all memfds */ case KDBUS_ITEM_PAYLOAD_MEMFD: - close(item->memfd.fd); + if (-1 != item->memfd.fd) + CLOSE(item->memfd.fd); break; case KDBUS_ITEM_FDS: nfds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof(int); for (i = 0; i < nfds; i++) - close(item->fds[i]); + if (-1 != item->fds[i]) + CLOSE(item->fds[i]); break; } } } -int kdbus_msg_recv(struct kdbus_conn *conn, +wur static int verify_padding(char const *b, unsigned off) +{ + while (off%8) { + ASSERT_ZERO((unsigned)b[off]); + ++off; + } + return 0; +} + +wur static int verify_string(unsigned size, char const *s) +{ + unsigned len; + ASSERT_NONZERO(size); + len = strlen(s)+1; + ASSERT_RETURN(len,==,size); + ASSERT_ZERO(verify_padding(s, len)); + return 0; +} +wur static int verify_string_array(unsigned size, char const *s) +{ + unsigned off=0; + ASSERT_NONZERO(size); + while (size) { + unsigned len = strlen(s+off); + if (!len) + break; + ++len; + ASSERT_RETURN(len,<=,size); + size -= len; + off += len; + } + ASSERT_ZERO(verify_padding(s, off)); + return 0; +} + +#define VERIFY_DECL\ + const struct kdbus_item *item;\ + unsigned item_count[14];\ + unsigned i;\ + memset(item_count, 0, sizeof(item_count)); +#define VERIFY_DECL_INLOOP\ + unsigned idx;\ + unsigned size;\ + ASSERT_RETURN(item->size,>=,2*sizeof(uint64_t));\ + ASSERT_RETURN((unsigned)item->size,==,item->size);\ + size = item->size - 2*sizeof(uint64_t); +#define VERIFY_META_CASES\ + /* metadata */\ + case KDBUS_ITEM_CREDS:\ + ASSERT_RETURN(size,==,sizeof(struct kdbus_creds));\ + break;\ + case KDBUS_ITEM_PIDS:\ + ASSERT_RETURN(size,==,sizeof(struct kdbus_pids));\ + break;\ + case KDBUS_ITEM_AUDIT:\ + ASSERT_RETURN(size,==,sizeof(struct kdbus_audit));\ + break;\ + case KDBUS_ITEM_AUXGROUPS:\ + case KDBUS_ITEM_CAPS:\ + ASSERT_ZERO(size%sizeof(uint32_t));\ + break;\ + case KDBUS_ITEM_OWNED_NAME:\ + ASSERT_ZERO(verify_string(size-offsetof(typeof(item->name), name), item->name.name));\ + break;\ + case KDBUS_ITEM_TID_COMM:\ + case KDBUS_ITEM_PID_COMM:\ + case KDBUS_ITEM_EXE:\ + case KDBUS_ITEM_CGROUP:\ + case KDBUS_ITEM_SECLABEL:\ + case KDBUS_ITEM_CONN_DESCRIPTION:\ + ASSERT_ZERO(verify_string(size, item->str));\ + break;\ + case KDBUS_ITEM_CMDLINE:\ + ASSERT_ZERO(verify_string_array(size, item->str));\ + break; +#define VERIFY_META do {\ + ASSERT_RETURN(item->type,>=,(uint64_t)_KDBUS_ITEM_ATTACH_BASE);\ + idx = item->type - _KDBUS_ITEM_ATTACH_BASE;\ + ASSERT_RETURN(idx,<,sizeof(item_count)/sizeof(*item_count));\ + ASSERT_NONZERO(attach_flags & 1<type)\ + ASSERT_ZERO(item_count[idx]);\ + else\ + ASSERT_RETURN(item_count[idx],<,(uint64_t)KDBUS_CONN_MAX_NAMES);\ + ++item_count[idx];\ +} while (0) +#define VERIFY_FINAL_ASSERT do {\ + for (i=0; itype) { + VERIFY_META_CASES; + default: ASSERT_ZERO(item->type ?: (uint64_t)-1); + } + VERIFY_META; + } + + VERIFY_FINAL_ASSERT; + + return 0; +} + +wur static int kdbus_msg_verify(struct kdbus_msg *msg, unsigned attach_flags) +{ + bool user = false; + + VERIFY_DECL; + + if (msg->payload_type != KDBUS_PAYLOAD_KERNEL) { + ASSERT_RETURN(msg->payload_type,==,KDBUS_PAYLOAD_DBUS); + user = true; + } + + KDBUS_ITEM_FOREACH(item, msg, items) { + VERIFY_DECL_INLOOP; + + switch(item->type) { + case KDBUS_ITEM_TIMESTAMP: + ASSERT_RETURN(size,==,sizeof(struct kdbus_timestamp)); + break; + VERIFY_META_CASES; + + /* user items */ + case KDBUS_ITEM_PAYLOAD_OFF: + ASSERT_NONZERO(user); + ASSERT_RETURN(size,==,sizeof(struct kdbus_vec)); + continue; + case KDBUS_ITEM_PAYLOAD_MEMFD: + ASSERT_NONZERO(user); + ASSERT_RETURN(size,==,sizeof(struct kdbus_memfd)); + continue; + case KDBUS_ITEM_FDS: + ASSERT_NONZERO(user); + ASSERT_ZERO(size%sizeof(int)); + continue; + case KDBUS_ITEM_DST_NAME: + ASSERT_NONZERO(user); + ASSERT_ZERO(verify_string(size, item->str)); + continue; + + /* kernel items */ + case KDBUS_ITEM_NAME_ADD: + case KDBUS_ITEM_NAME_REMOVE: + case KDBUS_ITEM_NAME_CHANGE: + ASSERT_ZERO(user); + ASSERT_RETURN(size,>=,sizeof(struct kdbus_notify_name_change)); + ASSERT_ZERO(verify_string(size-sizeof(struct kdbus_notify_name_change), item->name_change.name)); + continue; + case KDBUS_ITEM_ID_ADD: + case KDBUS_ITEM_ID_REMOVE: + ASSERT_ZERO(user); + ASSERT_RETURN(size,==,sizeof(struct kdbus_notify_id_change)); + continue; + case KDBUS_ITEM_REPLY_TIMEOUT: + case KDBUS_ITEM_REPLY_DEAD: + ASSERT_ZERO(user); + ASSERT_ZERO(size); + continue; + + case KDBUS_ITEM_BLOOM_FILTER: + kdbus_printf("WARNING! KDBUS_ITEM_BLOOM_FILTER passed from the kernel\n"); + continue; + + default: + ASSERT_ZERO(item->type ?: (uint64_t)-1); + } + if (KDBUS_ITEM_TIMESTAMP != item->type) + ASSERT_NONZERO(user); + VERIFY_META; + } + + /* we're requesting all metadata and that's what we mandate */ + if (user) { + VERIFY_FINAL_ASSERT; + if (attach_flags & 1 << (KDBUS_ITEM_TIMESTAMP-_KDBUS_ITEM_ATTACH_BASE)) + ASSERT_NONZERO(item_count[KDBUS_ITEM_TIMESTAMP-_KDBUS_ITEM_ATTACH_BASE]); + } else if (attach_flags & 1 << (KDBUS_ITEM_TIMESTAMP-_KDBUS_ITEM_ATTACH_BASE)) + ASSERT_NONZERO(item_count[KDBUS_ITEM_TIMESTAMP-_KDBUS_ITEM_ATTACH_BASE]); + + return 0; +} + +wur int kdbus_msg_recv(struct kdbus_conn *conn, struct kdbus_msg **msg_out, uint64_t *offset) { @@ -993,7 +1204,8 @@ int kdbus_msg_recv(struct kdbus_conn *conn, return ret; msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset); - ret = kdbus_msg_dump(conn, msg); + ret = kdbus_msg_dump(msg); + ASSERT_ZERO(kdbus_msg_verify(msg, conn->attach_flags_recv)); if (ret < 0) { kdbus_msg_free(msg); return ret; @@ -1021,7 +1233,7 @@ int kdbus_msg_recv(struct kdbus_conn *conn, * We must return -ETIMEDOUT, -ECONNREST, -EAGAIN and other errors. * We must return the result of kdbus_msg_recv() */ -int kdbus_msg_recv_poll(struct kdbus_conn *conn, +wur int kdbus_msg_recv_poll(struct kdbus_conn *conn, int timeout_ms, struct kdbus_msg **msg_out, uint64_t *offset) @@ -1064,7 +1276,7 @@ int kdbus_msg_recv_poll(struct kdbus_conn *conn, return ret; } -int kdbus_free(const struct kdbus_conn *conn, uint64_t offset) +wur int kdbus_free(const struct kdbus_conn *conn, uint64_t offset) { struct kdbus_cmd_free cmd_free = {}; int ret; @@ -1082,7 +1294,12 @@ int kdbus_free(const struct kdbus_conn *conn, uint64_t offset) return 0; } -int kdbus_name_acquire(struct kdbus_conn *conn, +wur int kdbus_free_msg(struct kdbus_conn const *conn, struct kdbus_msg *msg) +{ + return kdbus_free(conn, (uintptr_t)msg - (uintptr_t)conn->buf); +} + +wur int kdbus_name_acquire(struct kdbus_conn *conn, const char *name, uint64_t *flags) { struct kdbus_cmd *cmd_name; @@ -1106,7 +1323,7 @@ int kdbus_name_acquire(struct kdbus_conn *conn, ret = kdbus_cmd_name_acquire(conn->fd, cmd_name); if (ret < 0) { - kdbus_printf("error aquiring name: %s\n", strerror(-ret)); + kdbus_printf("error acquiring name: %s\n", strerror(-ret)); return ret; } @@ -1119,7 +1336,7 @@ int kdbus_name_acquire(struct kdbus_conn *conn, return 0; } -int kdbus_name_release(struct kdbus_conn *conn, const char *name) +wur int kdbus_name_release(struct kdbus_conn *conn, const char *name) { struct kdbus_cmd *cmd_name; size_t name_len = strlen(name) + 1; @@ -1150,7 +1367,7 @@ int kdbus_name_release(struct kdbus_conn *conn, const char *name) return 0; } -int kdbus_list(struct kdbus_conn *conn, uint64_t flags) +wur int kdbus_list(struct kdbus_conn *conn, uint64_t flags) { struct kdbus_cmd_list cmd_list = {}; struct kdbus_info *list, *name; @@ -1180,11 +1397,12 @@ int kdbus_list(struct kdbus_conn *conn, uint64_t flags) if (item->type == KDBUS_ITEM_OWNED_NAME) { n = item->name.name; flags = item->name.flags; - } - kdbus_printf("%8llu flags=0x%08llx conn=0x%08llx '%s'\n", - name->id, (unsigned long long) flags, - name->flags, n); + kdbus_printf("%8llu flags=0x%08llx conn=0x%08llx '%s'\n", + name->id, + (unsigned long long) flags, + name->flags, n); + } } kdbus_printf("\n"); @@ -1193,7 +1411,7 @@ int kdbus_list(struct kdbus_conn *conn, uint64_t flags) return ret; } -int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, +wur int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, uint64_t attach_flags_send, uint64_t attach_flags_recv) { @@ -1205,9 +1423,9 @@ int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, size = sizeof(struct kdbus_cmd); size += KDBUS_ITEM_SIZE(sizeof(uint64_t)) * 2; - update = malloc(size); + update = alloc(size); if (!update) { - kdbus_printf("error malloc: %m\n"); + kdbus_printf("error alloc: %m\n"); return -ENOMEM; } @@ -1231,11 +1449,12 @@ int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, kdbus_printf("error conn update: %d (%m)\n", ret); free(update); + conn->attach_flags_recv = attach_flags_recv; return ret; } -int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, +wur int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, const struct kdbus_policy_access *access, size_t num_access) { @@ -1248,9 +1467,9 @@ int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, size += KDBUS_ITEM_SIZE(strlen(name) + 1); size += num_access * KDBUS_ITEM_SIZE(sizeof(struct kdbus_policy_access)); - update = malloc(size); + update = alloc(size); if (!update) { - kdbus_printf("error malloc: %m\n"); + kdbus_printf("error alloc: %m\n"); return -ENOMEM; } @@ -1285,7 +1504,7 @@ int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, return ret; } -int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie, +wur int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie, uint64_t type, uint64_t id) { struct { @@ -1313,7 +1532,7 @@ int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie, return ret; } -int kdbus_add_match_empty(struct kdbus_conn *conn) +wur int kdbus_add_match_empty(struct kdbus_conn *conn) { struct { struct kdbus_cmd_match cmd; @@ -1336,7 +1555,7 @@ int kdbus_add_match_empty(struct kdbus_conn *conn) return ret; } -static int all_ids_are_mapped(const char *path) +static wur int all_ids_are_mapped(const char *path) { int ret; FILE *file; @@ -1374,7 +1593,7 @@ static int all_ids_are_mapped(const char *path) return 0; } -int all_uids_gids_are_mapped() +wur int all_uids_gids_are_mapped(void) { int ret; @@ -1393,7 +1612,7 @@ int all_uids_gids_are_mapped() return 1; } -int drop_privileges(uid_t uid, gid_t gid) +wur int drop_privileges(uid_t uid, gid_t gid) { int ret; @@ -1421,7 +1640,7 @@ int drop_privileges(uid_t uid, gid_t gid) return ret; } -uint64_t now(clockid_t clock) +wur uint64_t now(clockid_t clock) { struct timespec spec; @@ -1429,7 +1648,7 @@ uint64_t now(clockid_t clock) return spec.tv_sec * 1000ULL * 1000ULL * 1000ULL + spec.tv_nsec; } -char *unique_name(const char *prefix) +wur char *unique_name(const char *prefix) { unsigned int i; uint64_t u_now; @@ -1464,8 +1683,7 @@ char *unique_name(const char *prefix) return str; } -static int do_userns_map_id(pid_t pid, - const char *map_file, +static wur int do_userns_map_id(const char *map_file, const char *map_id) { int ret; @@ -1504,11 +1722,11 @@ static int do_userns_map_id(pid_t pid, ret = 0; out: - close(fd); + CLOSE(fd); return ret; } -int userns_map_uid_gid(pid_t pid, +wur int userns_map_uid_gid(pid_t pid, const char *map_uid, const char *map_gid) { @@ -1518,7 +1736,7 @@ int userns_map_uid_gid(pid_t pid, snprintf(file_id, sizeof(file_id), "/proc/%ld/uid_map", (long) pid); - ret = do_userns_map_id(pid, file_id, map_uid); + ret = do_userns_map_id(file_id, map_uid); if (ret < 0) return ret; @@ -1527,17 +1745,19 @@ int userns_map_uid_gid(pid_t pid, fd = open(file_id, O_WRONLY); if (fd >= 0) { - write(fd, "deny\n", 5); - close(fd); + ret = write(fd, "deny\n", 5); + CLOSE(fd); + if (ret != 5) + return ret<0 ? ret : -EIO; } snprintf(file_id, sizeof(file_id), "/proc/%ld/gid_map", (long) pid); - return do_userns_map_id(pid, file_id, map_gid); + return do_userns_map_id(file_id, map_gid); } -static int do_cap_get_flag(cap_t caps, cap_value_t cap) +static wur int do_cap_get_flag(cap_t caps, cap_value_t cap) { int ret; cap_flag_value_t flag_set; @@ -1561,14 +1781,14 @@ static int do_cap_get_flag(cap_t caps, cap_value_t cap) * * Terminate args with a negative value. */ -int test_is_capable(int cap, ...) +wur int test_is_capable(int cap, ...) { int ret; va_list ap; cap_t caps; caps = cap_get_proc(); - if (!cap) { + if (!caps) { ret = -errno; kdbus_printf("error cap_get_proc(): %d (%m)\n", ret); return ret; @@ -1591,22 +1811,22 @@ out: return ret; } -int config_user_ns_is_enabled(void) +wur int config_user_ns_is_enabled(void) { return (access("/proc/self/uid_map", F_OK) == 0); } -int config_auditsyscall_is_enabled(void) +wur int config_auditsyscall_is_enabled(void) { return (access("/proc/self/loginuid", F_OK) == 0); } -int config_cgroups_is_enabled(void) +wur int config_cgroups_is_enabled(void) { return (access("/proc/self/cgroup", F_OK) == 0); } -int config_security_is_enabled(void) +wur int config_security_is_enabled(void) { int fd; int ret; @@ -1630,7 +1850,7 @@ int config_security_is_enabled(void) else ret = 1; - close(fd); + CLOSE(fd); return ret; } diff --git a/tools/testing/selftests/kdbus/kdbus-util.h b/tools/testing/selftests/kdbus/kdbus-util.h index 652d957..654adc6f6 100644 --- a/tools/testing/selftests/kdbus/kdbus-util.h +++ b/tools/testing/selftests/kdbus/kdbus-util.h @@ -7,6 +7,7 @@ * Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. */ + #pragma once #define BIT(X) (1 << (X)) @@ -14,11 +15,52 @@ #include #include #include +#include + +/* backwards-incompatible tizen customizations */ +#define TIZEN +#ifdef TIZEN + #define ONTIZEN(TIZEN,NONTIZEN) TIZEN +#else + #define ONTIZEN(TIZEN,NONTIZEN) NONTIZEN +#endif + +/* c99 compat */ +#define typeof __typeof__ + +#define wur __attribute__((warn_unused_result)) + +#define print(...) fprintf(stderr, ##__VA_ARGS__) + +#define UNUSED(VAL) do { __auto_type _UNUSED_val_ = (VAL); (void)_UNUSED_val_; } while (0) + +#define TABSIZE(T) (sizeof(T)/sizeof(T[0])) + +static inline wur void *alloc(size_t size) { + void *p; + int ret = posix_memalign(&p, 8, size); + return ret ? NULL : p; +} + +#define MAX(A,B) ({\ + typeof(A) __MAX__A__ = (A);\ + typeof(B) __MAX__B__ = (B);\ + __MAX__A__<__MAX__B__ ? __MAX__B__ : __MAX__A__;\ +}) +#define MIN(A,B) ({\ + typeof(A) __MIN__A__ = (A);\ + typeof(B) __MIN__B__ = (B);\ + __MIN__A__>__MIN__B__ ? __MIN__B__ : __MIN__A__;\ +}) + +#define KDBUS_TIMEOUT_INFINITE 0x3fffffffffffffffULL #define _STRINGIFY(x) #x #define STRINGIFY(x) _STRINGIFY(x) #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) +#define fail(FMT,...) do { print("[" __FILE__ ":" STRINGIFY(__LINE__) "] fail " FMT "\n", ##__VA_ARGS__); exit(2); } while (0) + #define KDBUS_PTR(addr) ((void *)(uintptr_t)(addr)) #define KDBUS_ALIGN8(l) (((l) + 7) & ~7) @@ -26,28 +68,26 @@ #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) #define KDBUS_ITEM_NEXT(item) \ - (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) + (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size)) #define KDBUS_ITEM_FOREACH(item, head, first) \ - for (item = (head)->first; \ + for ((item) = (head)->first; \ ((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) && \ - ((uint8_t *)(item) >= (uint8_t *)(head)); \ - item = KDBUS_ITEM_NEXT(item)) + ((uint8_t *)(item) >= (uint8_t *)(head)); \ + (item) = KDBUS_ITEM_NEXT(item)) #define KDBUS_FOREACH(iter, first, _size) \ - for (iter = (first); \ + for ((iter) = (first); \ ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ ((uint8_t *)(iter) >= (uint8_t *)(first)); \ - iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size))) - + (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size))) -#define _KDBUS_ATTACH_BITS_SET_NR (__builtin_popcountll(_KDBUS_ATTACH_ALL)) +#define _KDBUS_ATTACH_BITS_SET_NR (__builtin_popcountll(_KDBUS_ATTACH_ALL)) /* Sum of KDBUS_ITEM_* that reflects _KDBUS_ATTACH_ALL */ -#define KDBUS_ATTACH_ITEMS_TYPE_SUM \ - ((((_KDBUS_ATTACH_BITS_SET_NR - 1) * \ - ((_KDBUS_ATTACH_BITS_SET_NR - 1) + 1)) / 2 ) + \ +#define KDBUS_ATTACH_ITEMS_TYPE_SUM \ + ((((_KDBUS_ATTACH_BITS_SET_NR - 1) * \ + ((_KDBUS_ATTACH_BITS_SET_NR - 1) + 1)) / 2) + \ (_KDBUS_ITEM_ATTACH_BASE * _KDBUS_ATTACH_BITS_SET_NR)) - #define POOL_SIZE (16 * 1024LU * 1024LU) #define UNPRIV_UID 65534 @@ -60,41 +100,43 @@ extern int kdbus_util_verbose; #define kdbus_printf(X...) \ if (kdbus_util_verbose) \ - printf(X) + print(X) -#define RUN_UNPRIVILEGED(child_uid, child_gid, _child_, _parent_) ({ \ - pid_t pid, rpid; \ - int ret; \ - \ - pid = fork(); \ - if (pid == 0) { \ - ret = drop_privileges(child_uid, child_gid); \ - ASSERT_EXIT_VAL(ret == 0, ret); \ - \ - _child_; \ - _exit(0); \ - } else if (pid > 0) { \ - _parent_; \ - rpid = waitpid(pid, &ret, 0); \ - ASSERT_RETURN(rpid == pid); \ - ASSERT_RETURN(WIFEXITED(ret)); \ - ASSERT_RETURN(WEXITSTATUS(ret) == 0); \ - ret = TEST_OK; \ - } else { \ - ret = pid; \ - } \ - \ - ret; \ - }) +#define RUN_FORKED(_child_, _parent_) ASSERT_ZERO(({\ + pid_t pid, rpid;\ + int ret;\ + \ + pid = fork();\ + if (pid == 0) {\ + _child_;\ + exit(0);\ + } else if (pid > 0) {\ + _parent_;\ + rpid = waitpid(pid, &ret, 0);\ + ASSERT_RETURN(rpid,==,pid);\ + ASSERT_NONZERO(WIFEXITED(ret));\ + ASSERT_ZERO(WEXITSTATUS(ret));\ + ret = TEST_OK;\ + } else {\ + ret = pid;\ + }\ + \ + ret;\ + })) + +#define RUN_UNPRIVILEGED(child_uid, child_gid, _child_, _parent_) RUN_FORKED(({\ + ret = drop_privileges(child_uid, child_gid);\ + ASSERT_EXIT_VAL(ret,==,0, ret);\ + _child_;\ + }), _parent_) #define RUN_UNPRIVILEGED_CONN(_var_, _bus_, _code_) \ RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ \ struct kdbus_conn *_var_; \ - _var_ = kdbus_hello(_bus_, 0, NULL, 0); \ - ASSERT_EXIT(_var_); \ + ASSERT_EXIT_NONZERO(_var_ = kdbus_hello(_bus_, 0, NULL, 0)); \ _code_; \ kdbus_conn_free(_var_); \ - }), ({ 0; })) + }), ({})) #define RUN_CLONE_CHILD(clone_ret, flags, _setup_, _child_body_, \ _parent_setup_, _parent_body_) ({ \ @@ -104,38 +146,45 @@ extern int kdbus_util_verbose; \ _setup_; \ efd = eventfd(0, EFD_CLOEXEC); \ - ASSERT_RETURN(efd >= 0); \ - *clone_ret = 0; \ + ASSERT_RETURN(efd,>=,0); \ + *(clone_ret) = 0; \ pid = syscall(__NR_clone, flags, NULL); \ if (pid == 0) { \ eventfd_t event_status = 0; \ - ret = prctl(PR_SET_PDEATHSIG, SIGKILL); \ - ASSERT_EXIT(ret == 0); \ + ASSERT_EXIT_ZERO(prctl(PR_SET_PDEATHSIG, SIGKILL)); \ ret = eventfd_read(efd, &event_status); \ if (ret < 0 || event_status != 1) { \ kdbus_printf("error eventfd_read()\n"); \ - _exit(EXIT_FAILURE); \ + exit(EXIT_FAILURE); \ } \ _child_body_; \ - _exit(0); \ + exit(0); \ } else if (pid > 0) { \ _parent_setup_; \ - ret = eventfd_write(efd, 1); \ - ASSERT_RETURN(ret >= 0); \ + ASSERT_RETURN(eventfd_write(efd, 1),>=,0); \ _parent_body_; \ rpid = waitpid(pid, &ret, 0); \ - ASSERT_RETURN(rpid == pid); \ - ASSERT_RETURN(WIFEXITED(ret)); \ - ASSERT_RETURN(WEXITSTATUS(ret) == 0); \ + ASSERT_RETURN(rpid,==,pid); \ + ASSERT_NONZERO(WIFEXITED(ret)); \ + ASSERT_ZERO(WEXITSTATUS(ret)); \ ret = TEST_OK; \ } else { \ ret = -errno; \ - *clone_ret = -errno; \ + *(clone_ret) = -errno; \ } \ - close(efd); \ + CLOSE(efd); \ ret; \ }) +#define ASSERT_NO_PENDING(CONN) do {\ + struct kdbus_cmd_recv _ASSERT_NO_PENDING_recv_ = { .size = sizeof(_ASSERT_NO_PENDING_recv_) };\ + int _ASSERT_NO_PENDING_fd_ = (CONN)->fd;\ + int _ASSERT_NO_PENDING_ret_ = kdbus_cmd_recv(_ASSERT_NO_PENDING_fd_, &_ASSERT_NO_PENDING_recv_);\ + ASSERT_RETURN(-EAGAIN,==,_ASSERT_NO_PENDING_ret_);\ +} while (0) + +#define CLOSE(...) do { __auto_type _CLOSE_fd_ = (__VA_ARGS__); if (close(_CLOSE_fd_)) fail("close(%d) err(%d)", _CLOSE_fd_, errno); } while (0) + /* Enums for parent if it should drop privs or not */ enum kdbus_drop_parent { DO_NOT_DROP, @@ -146,77 +195,76 @@ enum kdbus_drop_parent { struct kdbus_conn { int fd; uint64_t id; + unsigned attach_flags_recv; unsigned char *buf; }; -int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask); -int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask); +wur int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask); +wur int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask); -int sys_memfd_create(const char *name, __u64 size); -int sys_memfd_seal_set(int fd); -off_t sys_memfd_get_size(int fd, off_t *size); +wur int sys_memfd_create(const char *name, __u64 size); +wur int sys_memfd_seal_set(int fd); +wur off_t sys_memfd_get_size(int fd, off_t *size); -int kdbus_list(struct kdbus_conn *conn, uint64_t flags); -int kdbus_name_release(struct kdbus_conn *conn, const char *name); -int kdbus_name_acquire(struct kdbus_conn *conn, const char *name, +wur int kdbus_list(struct kdbus_conn *conn, uint64_t flags); +wur int kdbus_name_release(struct kdbus_conn *conn, const char *name); +wur int kdbus_name_acquire(struct kdbus_conn *conn, const char *name, uint64_t *flags); void kdbus_msg_free(struct kdbus_msg *msg); -int kdbus_msg_recv(struct kdbus_conn *conn, +wur int kdbus_msg_recv(struct kdbus_conn *conn, struct kdbus_msg **msg, uint64_t *offset); -int kdbus_msg_recv_poll(struct kdbus_conn *conn, int timeout_ms, +wur int kdbus_msg_recv_poll(struct kdbus_conn *conn, int timeout_ms, struct kdbus_msg **msg_out, uint64_t *offset); -int kdbus_free(const struct kdbus_conn *conn, uint64_t offset); -int kdbus_msg_dump(const struct kdbus_conn *conn, - const struct kdbus_msg *msg); -int kdbus_create_bus(int control_fd, const char *name, - uint64_t req_meta, uint64_t owner_meta, - char **path); -int kdbus_msg_send(const struct kdbus_conn *conn, const char *name, +wur int kdbus_free(const struct kdbus_conn *conn, uint64_t offset); +wur int kdbus_free_msg(struct kdbus_conn const *conn, struct kdbus_msg *msg); +wur int kdbus_msg_dump(const struct kdbus_msg *msg); +wur int kdbus_create_bus(int control_fd, const char *name, + uint64_t owner_meta, char **path); +wur int kdbus_msg_send(const struct kdbus_conn *conn, const char *name, uint64_t cookie, uint64_t flags, uint64_t timeout, - int64_t priority, uint64_t dst_id, int fds_count, int fds[]); -int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name, + int64_t priority, uint64_t dst_id); +wur int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name, uint64_t cookie, uint64_t flags, uint64_t timeout, int64_t priority, uint64_t dst_id, int cancel_fd); -int kdbus_msg_send_reply(const struct kdbus_conn *conn, +wur int kdbus_msg_send_reply(const struct kdbus_conn *conn, uint64_t reply_cookie, uint64_t dst_id); -struct kdbus_conn *kdbus_hello(const char *path, uint64_t hello_flags, +wur struct kdbus_conn *kdbus_hello(const char *path, uint64_t hello_flags, const struct kdbus_item *item, size_t item_size); -struct kdbus_conn *kdbus_hello_registrar(const char *path, const char *name, +wur int timeout_msg_recv(struct kdbus_conn *conn, uint64_t type, uint64_t *cookie_reply, uint64_t *seqnum, uint64_t *monotonic_ns, uint64_t *realtime_ns); +wur struct kdbus_conn *kdbus_hello_registrar(const char *path, const char *name, const struct kdbus_policy_access *access, size_t num_access, uint64_t flags); -struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name, +wur struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name, const struct kdbus_policy_access *access, size_t num_access); -bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type); -int kdbus_bus_creator_info(struct kdbus_conn *conn, +wur bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type); +wur int kdbus_bus_creator_info(struct kdbus_conn *conn, uint64_t flags, uint64_t *offset); -int kdbus_conn_info(struct kdbus_conn *conn, uint64_t id, +wur int kdbus_conn_info(struct kdbus_conn *conn, uint64_t id, const char *name, uint64_t flags, uint64_t *offset); void kdbus_conn_free(struct kdbus_conn *conn); -int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, +wur int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, uint64_t attach_flags_send, uint64_t attach_flags_recv); -int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, +wur int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, const struct kdbus_policy_access *access, size_t num_access); -int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie, +wur int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie, uint64_t type, uint64_t id); -int kdbus_add_match_empty(struct kdbus_conn *conn); - -int all_uids_gids_are_mapped(); -int drop_privileges(uid_t uid, gid_t gid); -uint64_t now(clockid_t clock); -char *unique_name(const char *prefix); - -int userns_map_uid_gid(pid_t pid, - const char *map_uid, - const char *map_gid); -int test_is_capable(int cap, ...); -int config_user_ns_is_enabled(void); -int config_auditsyscall_is_enabled(void); -int config_cgroups_is_enabled(void); -int config_security_is_enabled(void); +wur int kdbus_add_match_empty(struct kdbus_conn *conn); + +wur int all_uids_gids_are_mapped(void); +wur int drop_privileges(uid_t uid, gid_t gid); +wur uint64_t now(clockid_t clock); +wur char *unique_name(const char *prefix); + +wur int userns_map_uid_gid(pid_t pid, const char *map_uid, const char *map_gid); +wur int test_is_capable(int cap, ...); +wur int config_user_ns_is_enabled(void); +wur int config_auditsyscall_is_enabled(void); +wur int config_cgroups_is_enabled(void); +wur int config_security_is_enabled(void); \ No newline at end of file diff --git a/tools/testing/selftests/kdbus/test-activator.c b/tools/testing/selftests/kdbus/test-activator.c index c70fafe..f2a401c 100644 --- a/tools/testing/selftests/kdbus/test-activator.c +++ b/tools/testing/selftests/kdbus/test-activator.c @@ -18,7 +18,7 @@ #include "kdbus-util.h" #include "kdbus-enum.h" -static int kdbus_starter_poll(struct kdbus_conn *conn) +static wur int kdbus_starter_poll(struct kdbus_conn *conn) { int ret; struct pollfd fd; @@ -42,12 +42,11 @@ static int kdbus_starter_poll(struct kdbus_conn *conn) } /* Ensure that kdbus activator logic is safe */ -static int kdbus_priv_activator(struct kdbus_test_env *env) +static wur int kdbus_priv_activator(struct kdbus_test_env *env) { - int ret; struct kdbus_msg *msg = NULL; uint64_t cookie = 0xdeadbeef; - uint64_t flags = KDBUS_NAME_REPLACE_EXISTING; + uint64_t flags; struct kdbus_conn *activator; struct kdbus_conn *service; struct kdbus_conn *client; @@ -69,39 +68,37 @@ static int kdbus_priv_activator(struct kdbus_test_env *env) activator = kdbus_hello_activator(env->buspath, "foo.priv.activator", access, 2); - ASSERT_RETURN(activator); + ASSERT_NONZERO(activator); service = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(service); + ASSERT_NONZERO(service); client = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(client); + ASSERT_NONZERO(client); /* * Make sure that other users can't TALK to the activator */ - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ /* Try to talk using the ID */ ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef, 0, 0, - 0, activator->id, 0, NULL); - ASSERT_EXIT(ret == -ENXIO); + 0, activator->id); + ASSERT_EXIT(ret,==,-ENXIO); /* Try to talk to the name */ ret = kdbus_msg_send(unpriv, "foo.priv.activator", 0xdeadbeef, 0, 0, 0, - KDBUS_DST_ID_NAME, 0, NULL); - ASSERT_EXIT(ret == -EPERM); + KDBUS_DST_ID_NAME); + ASSERT_EXIT(ret,==,ONTIZEN(0,-EPERM)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure that we did not receive anything, so the * service will not be started automatically */ - ret = kdbus_starter_poll(activator); - ASSERT_RETURN(ret == -ETIMEDOUT); + ASSERT_RETURN(ONTIZEN(0,-ETIMEDOUT),==,kdbus_starter_poll(activator)); /* * Now try to emulate the starter/service logic and @@ -109,56 +106,53 @@ static int kdbus_priv_activator(struct kdbus_test_env *env) */ cookie++; - ret = kdbus_msg_send(service, "foo.priv.activator", cookie, - 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(service, "foo.priv.activator", cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); - ret = kdbus_starter_poll(activator); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_starter_poll(activator)); /* Policies are still checked, access denied */ - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "foo.priv.activator", - &flags); - ASSERT_RETURN(ret == -EPERM); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + flags = KDBUS_NAME_REPLACE_EXISTING; + ASSERT_RETURN(ONTIZEN(0,-EPERM),==,kdbus_name_acquire(unpriv, "foo.priv.activator", &flags)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_name_acquire(service, "foo.priv.activator", - &flags); - ASSERT_RETURN(ret == 0); + flags = KDBUS_NAME_REPLACE_EXISTING; + ASSERT_ZERO(kdbus_name_acquire(service, "foo.priv.activator", &flags)); - /* We read our previous starter message */ +#ifdef TIZEN + ASSERT_ZERO(kdbus_msg_recv_poll(service, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie-1); + kdbus_msg_free(msg); +#endif - ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(service, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); + kdbus_msg_free(msg); /* Try to talk, we still fail */ cookie++; - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ /* Try to talk to the name */ - ret = kdbus_msg_send(unpriv, "foo.priv.activator", - cookie, 0, 0, 0, - KDBUS_DST_ID_NAME, 0, NULL); - ASSERT_EXIT(ret == -EPERM); + ASSERT_EXIT(ONTIZEN(0,-EPERM),==,kdbus_msg_send(unpriv, "foo.priv.activator", cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); })); - ASSERT_RETURN(ret >= 0); +#ifdef TIZEN + ASSERT_ZERO(kdbus_msg_recv_poll(service, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); + kdbus_msg_free(msg); +#endif /* Still nothing to read */ - ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); - ASSERT_RETURN(ret == -ETIMEDOUT); + ASSERT_RETURN(-ETIMEDOUT,==,kdbus_msg_recv_poll(service, 100, NULL, NULL)); /* We receive every thing now */ cookie++; - ret = kdbus_msg_send(client, "foo.priv.activator", cookie, - 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_recv_poll(service, 100, &msg, NULL); - ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_send(client, "foo.priv.activator", cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); + ASSERT_ZERO(kdbus_msg_recv_poll(service, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); @@ -166,26 +160,22 @@ static int kdbus_priv_activator(struct kdbus_test_env *env) kdbus_conn_free(activator); cookie++; - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ /* Try to talk to the name */ - ret = kdbus_msg_send(unpriv, "foo.priv.activator", - cookie, 0, 0, 0, - KDBUS_DST_ID_NAME, - 0, NULL); - ASSERT_EXIT(ret == -EPERM); + ASSERT_EXIT(ONTIZEN(0,-EPERM),==,kdbus_msg_send(unpriv, "foo.priv.activator", cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); - ASSERT_RETURN(ret == -ETIMEDOUT); + ASSERT_RETURN(ONTIZEN(0,-ETIMEDOUT),==,kdbus_msg_recv_poll(service, 100, &msg, NULL)); +#ifdef TIZEN + ASSERT_RETURN(msg->cookie,==,cookie); + kdbus_msg_free(msg); +#endif /* Same user is able to TALK */ cookie++; - ret = kdbus_msg_send(client, "foo.priv.activator", cookie, - 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_recv_poll(service, 100, &msg, NULL); - ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_send(client, "foo.priv.activator", cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); + ASSERT_ZERO(kdbus_msg_recv_poll(service, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); @@ -199,30 +189,22 @@ static int kdbus_priv_activator(struct kdbus_test_env *env) holder = kdbus_hello_registrar(env->buspath, "foo.priv.activator", access, 1, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(holder); + ASSERT_NONZERO(holder); /* Now we are able to TALK to the name */ cookie++; - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ /* Try to talk to the name */ - ret = kdbus_msg_send(unpriv, "foo.priv.activator", - cookie, 0, 0, 0, - KDBUS_DST_ID_NAME, - 0, NULL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, "foo.priv.activator", cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(service, 100, NULL, NULL)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "foo.priv.activator", - &flags); - ASSERT_RETURN(ret == -EPERM); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + flags = KDBUS_NAME_REPLACE_EXISTING; + ASSERT_EXIT(ONTIZEN(-EEXIST,-EPERM),==,kdbus_name_acquire(unpriv, "foo.priv.activator", &flags)); })); - ASSERT_RETURN(ret >= 0); kdbus_conn_free(service); kdbus_conn_free(client); @@ -231,7 +213,7 @@ static int kdbus_priv_activator(struct kdbus_test_env *env) return 0; } -int kdbus_test_activator(struct kdbus_test_env *env) +wur int kdbus_test_activator(struct kdbus_test_env *env) { int ret; struct kdbus_conn *activator; @@ -248,20 +230,13 @@ int kdbus_test_activator(struct kdbus_test_env *env) activator = kdbus_hello_activator(env->buspath, "foo.test.activator", access, 2); - ASSERT_RETURN(activator); + ASSERT_NONZERO(activator); - ret = kdbus_add_match_empty(env->conn); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(env->conn)); - ret = kdbus_list(env->conn, KDBUS_LIST_NAMES | - KDBUS_LIST_UNIQUE | - KDBUS_LIST_ACTIVATORS | - KDBUS_LIST_QUEUED); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_list(env->conn, KDBUS_LIST_NAMES | KDBUS_LIST_UNIQUE | KDBUS_LIST_ACTIVATORS | KDBUS_LIST_QUEUED)); - ret = kdbus_msg_send(env->conn, "foo.test.activator", 0xdeafbeef, - 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, "foo.test.activator", 0xdeafbeef, 0, 0, 0, KDBUS_DST_ID_NAME)); fds[0].fd = activator->fd; fds[1].fd = env->conn->fd; @@ -277,25 +252,22 @@ int kdbus_test_activator(struct kdbus_test_env *env) } ret = poll(fds, nfds, 3000); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); - ret = kdbus_list(env->conn, KDBUS_LIST_NAMES); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_list(env->conn, KDBUS_LIST_NAMES)); if ((fds[0].revents & POLLIN) && !activator_done) { uint64_t flags = KDBUS_NAME_REPLACE_EXISTING; kdbus_printf("Starter was called back!\n"); - ret = kdbus_name_acquire(env->conn, - "foo.test.activator", &flags); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(env->conn, "foo.test.activator", &flags)); activator_done = true; } if (fds[1].revents & POLLIN) { - kdbus_msg_recv(env->conn, NULL, NULL); + ASSERT_ZERO(kdbus_msg_recv(env->conn, NULL, NULL)); break; } } @@ -306,13 +278,12 @@ int kdbus_test_activator(struct kdbus_test_env *env) /* Check now capabilities, so we run the previous tests */ ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); if (!ret) return TEST_SKIP; - ret = kdbus_priv_activator(env); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_priv_activator(env)); kdbus_conn_free(activator); diff --git a/tools/testing/selftests/kdbus/test-attach-flags.c b/tools/testing/selftests/kdbus/test-attach-flags.c deleted file mode 100644 index deee7c3..0000000 --- a/tools/testing/selftests/kdbus/test-attach-flags.c +++ /dev/null @@ -1,750 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kdbus-api.h" -#include "kdbus-test.h" -#include "kdbus-util.h" -#include "kdbus-enum.h" - -/* - * Should be the sum of the currently supported and compiled-in - * KDBUS_ITEMS_* that reflect KDBUS_ATTACH_* flags. - */ -static unsigned int KDBUS_TEST_ITEMS_SUM = KDBUS_ATTACH_ITEMS_TYPE_SUM; - -static struct kdbus_conn *__kdbus_hello(const char *path, uint64_t flags, - uint64_t attach_flags_send, - uint64_t attach_flags_recv) -{ - struct kdbus_cmd_free cmd_free = {}; - int ret, fd; - struct kdbus_conn *conn; - struct { - struct kdbus_cmd_hello hello; - - struct { - uint64_t size; - uint64_t type; - char str[16]; - } conn_name; - - uint8_t extra_items[0]; - } h; - - memset(&h, 0, sizeof(h)); - - kdbus_printf("-- opening bus connection %s\n", path); - fd = open(path, O_RDWR|O_CLOEXEC); - if (fd < 0) { - kdbus_printf("--- error %d (%m)\n", fd); - return NULL; - } - - h.hello.flags = flags | KDBUS_HELLO_ACCEPT_FD; - h.hello.attach_flags_send = attach_flags_send; - h.hello.attach_flags_recv = attach_flags_recv; - h.conn_name.type = KDBUS_ITEM_CONN_DESCRIPTION; - strcpy(h.conn_name.str, "this-is-my-name"); - h.conn_name.size = KDBUS_ITEM_HEADER_SIZE + strlen(h.conn_name.str) + 1; - - h.hello.size = sizeof(h); - h.hello.pool_size = POOL_SIZE; - - ret = kdbus_cmd_hello(fd, (struct kdbus_cmd_hello *) &h.hello); - if (ret < 0) { - kdbus_printf("--- error when saying hello: %d (%m)\n", ret); - return NULL; - } - - kdbus_printf("-- New connection ID : %llu\n", - (unsigned long long)h.hello.id); - - cmd_free.size = sizeof(cmd_free); - cmd_free.offset = h.hello.offset; - ret = kdbus_cmd_free(fd, &cmd_free); - if (ret < 0) - return NULL; - - conn = malloc(sizeof(*conn)); - if (!conn) { - kdbus_printf("unable to malloc()!?\n"); - return NULL; - } - - conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); - if (conn->buf == MAP_FAILED) { - ret = -errno; - free(conn); - close(fd); - kdbus_printf("--- error mmap: %d (%m)\n", ret); - return NULL; - } - - conn->fd = fd; - conn->id = h.hello.id; - return conn; -} - -static int kdbus_test_peers_creation(struct kdbus_test_env *env) -{ - int ret; - int control_fd; - char *path; - char *busname; - char buspath[2048]; - char control_path[2048]; - uint64_t attach_flags_mask; - struct kdbus_conn *conn; - - snprintf(control_path, sizeof(control_path), - "%s/control", env->root); - - /* - * Set kdbus system-wide mask to 0, this has nothing - * to do with the following tests, bus and connection - * creation nor connection update, but we do it so we are - * sure that everything work as expected - */ - - attach_flags_mask = 0; - ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path, - attach_flags_mask); - ASSERT_RETURN(ret == 0); - - - /* - * Create bus with a full set of ATTACH flags - */ - - control_fd = open(control_path, O_RDWR); - ASSERT_RETURN(control_fd >= 0); - - busname = unique_name("test-peers-creation-bus"); - ASSERT_RETURN(busname); - - ret = kdbus_create_bus(control_fd, busname, _KDBUS_ATTACH_ALL, - 0, &path); - ASSERT_RETURN(ret == 0); - - snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path); - - /* - * Create a connection with an empty send attach flags, or - * with just KDBUS_ATTACH_CREDS, this should fail - */ - conn = __kdbus_hello(buspath, 0, 0, 0); - ASSERT_RETURN(conn == NULL); - ASSERT_RETURN(errno == ECONNREFUSED); - - conn = __kdbus_hello(buspath, 0, KDBUS_ATTACH_CREDS, - _KDBUS_ATTACH_ALL); - ASSERT_RETURN(conn == NULL); - ASSERT_RETURN(errno == ECONNREFUSED); - - conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0); - ASSERT_RETURN(conn); - - /* Try to cut back some send attach flags */ - ret = kdbus_conn_update_attach_flags(conn, - KDBUS_ATTACH_CREDS| - KDBUS_ATTACH_PIDS, - _KDBUS_ATTACH_ALL); - ASSERT_RETURN(ret == -EINVAL); - - ret = kdbus_conn_update_attach_flags(conn, - _KDBUS_ATTACH_ALL, 0); - ASSERT_RETURN(ret == 0); - - kdbus_conn_free(conn); - free(path); - free(busname); - close(control_fd); - - - /* Test a new bus with KDBUS_ATTACH_PIDS */ - - control_fd = open(control_path, O_RDWR); - ASSERT_RETURN(control_fd >= 0); - - busname = unique_name("test-peer-flags-bus"); - ASSERT_RETURN(busname); - - ret = kdbus_create_bus(control_fd, busname, KDBUS_ATTACH_PIDS, - 0, &path); - ASSERT_RETURN(ret == 0); - - snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path); - - /* - * Create a connection with an empty send attach flags, or - * all flags except KDBUS_ATTACH_PIDS - */ - conn = __kdbus_hello(buspath, 0, 0, 0); - ASSERT_RETURN(conn == NULL); - ASSERT_RETURN(errno == ECONNREFUSED); - - conn = __kdbus_hello(buspath, 0, - _KDBUS_ATTACH_ALL & ~KDBUS_ATTACH_PIDS, - _KDBUS_ATTACH_ALL); - ASSERT_RETURN(conn == NULL); - ASSERT_RETURN(errno == ECONNREFUSED); - - /* The following should succeed */ - conn = __kdbus_hello(buspath, 0, KDBUS_ATTACH_PIDS, 0); - ASSERT_RETURN(conn); - kdbus_conn_free(conn); - - conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0); - ASSERT_RETURN(conn); - - ret = kdbus_conn_update_attach_flags(conn, - _KDBUS_ATTACH_ALL & - ~KDBUS_ATTACH_PIDS, - _KDBUS_ATTACH_ALL); - ASSERT_RETURN(ret == -EINVAL); - - ret = kdbus_conn_update_attach_flags(conn, 0, - _KDBUS_ATTACH_ALL); - ASSERT_RETURN(ret == -EINVAL); - - /* Now we want only KDBUS_ATTACH_PIDS */ - ret = kdbus_conn_update_attach_flags(conn, - KDBUS_ATTACH_PIDS, 0); - ASSERT_RETURN(ret == 0); - - kdbus_conn_free(conn); - free(path); - free(busname); - close(control_fd); - - - /* - * Create bus with 0 as ATTACH flags, the bus does not - * require any attach flags - */ - - control_fd = open(control_path, O_RDWR); - ASSERT_RETURN(control_fd >= 0); - - busname = unique_name("test-peer-flags-bus"); - ASSERT_RETURN(busname); - - ret = kdbus_create_bus(control_fd, busname, 0, 0, &path); - ASSERT_RETURN(ret == 0); - - snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path); - - /* Bus is open it does not require any send attach flags */ - conn = __kdbus_hello(buspath, 0, 0, 0); - ASSERT_RETURN(conn); - kdbus_conn_free(conn); - - conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0); - ASSERT_RETURN(conn); - - ret = kdbus_conn_update_attach_flags(conn, 0, 0); - ASSERT_RETURN(ret == 0); - - ret = kdbus_conn_update_attach_flags(conn, KDBUS_ATTACH_CREDS, 0); - ASSERT_RETURN(ret == 0); - - kdbus_conn_free(conn); - free(path); - free(busname); - close(control_fd); - - return 0; -} - -static int kdbus_test_peers_info(struct kdbus_test_env *env) -{ - int ret; - int control_fd; - char *path; - char *busname; - unsigned int i = 0; - uint64_t offset = 0; - char buspath[2048]; - char control_path[2048]; - uint64_t attach_flags_mask; - struct kdbus_item *item; - struct kdbus_info *info; - struct kdbus_conn *conn; - struct kdbus_conn *reader; - unsigned long long attach_count = 0; - - snprintf(control_path, sizeof(control_path), - "%s/control", env->root); - - attach_flags_mask = 0; - ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path, - attach_flags_mask); - ASSERT_RETURN(ret == 0); - - control_fd = open(control_path, O_RDWR); - ASSERT_RETURN(control_fd >= 0); - - busname = unique_name("test-peers-info-bus"); - ASSERT_RETURN(busname); - - ret = kdbus_create_bus(control_fd, busname, _KDBUS_ATTACH_ALL, - 0, &path); - ASSERT_RETURN(ret == 0); - - snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path); - - /* Create connections with the appropriate flags */ - conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0); - ASSERT_RETURN(conn); - - reader = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0); - ASSERT_RETURN(reader); - - ret = kdbus_conn_info(reader, conn->id, NULL, - _KDBUS_ATTACH_ALL, &offset); - ASSERT_RETURN(ret == 0); - - info = (struct kdbus_info *)(reader->buf + offset); - ASSERT_RETURN(info->id == conn->id); - - /* all attach flags are masked, no metadata */ - KDBUS_ITEM_FOREACH(item, info, items) - i++; - - ASSERT_RETURN(i == 0); - - kdbus_free(reader, offset); - - /* Set the mask to _KDBUS_ATTACH_ANY */ - attach_flags_mask = _KDBUS_ATTACH_ANY; - ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path, - attach_flags_mask); - ASSERT_RETURN(ret == 0); - - ret = kdbus_conn_info(reader, conn->id, NULL, - _KDBUS_ATTACH_ALL, &offset); - ASSERT_RETURN(ret == 0); - - info = (struct kdbus_info *)(reader->buf + offset); - ASSERT_RETURN(info->id == conn->id); - - attach_count = 0; - KDBUS_ITEM_FOREACH(item, info, items) - attach_count += item->type; - - /* - * All flags have been returned except for: - * KDBUS_ITEM_TIMESTAMP and - * KDBUS_ITEM_OWNED_NAME we do not own any name. - */ - ASSERT_RETURN(attach_count == (KDBUS_TEST_ITEMS_SUM - - KDBUS_ITEM_OWNED_NAME - - KDBUS_ITEM_TIMESTAMP)); - - kdbus_free(reader, offset); - - /* Request only OWNED names */ - ret = kdbus_conn_info(reader, conn->id, NULL, - KDBUS_ATTACH_NAMES, &offset); - ASSERT_RETURN(ret == 0); - - info = (struct kdbus_info *)(reader->buf + offset); - ASSERT_RETURN(info->id == conn->id); - - attach_count = 0; - KDBUS_ITEM_FOREACH(item, info, items) - attach_count += item->type; - - /* we should not get any metadata since we do not own names */ - ASSERT_RETURN(attach_count == 0); - - kdbus_free(reader, offset); - - kdbus_conn_free(conn); - kdbus_conn_free(reader); - - return 0; -} - -/** - * @kdbus_mask_param: kdbus module mask parameter (system-wide) - * @requested_meta: The bus owner metadata that we want - * @expected_items: The returned KDBUS_ITEMS_* sum. Used to - * validate the returned metadata items - */ -static int kdbus_cmp_bus_creator_metadata(struct kdbus_test_env *env, - struct kdbus_conn *conn, - uint64_t kdbus_mask_param, - uint64_t requested_meta, - unsigned long expected_items) -{ - int ret; - uint64_t offset = 0; - struct kdbus_info *info; - struct kdbus_item *item; - unsigned long attach_count = 0; - - ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path, - kdbus_mask_param); - ASSERT_RETURN(ret == 0); - - ret = kdbus_bus_creator_info(conn, requested_meta, &offset); - ASSERT_RETURN(ret == 0); - - info = (struct kdbus_info *)(conn->buf + offset); - - KDBUS_ITEM_FOREACH(item, info, items) - attach_count += item->type; - - ASSERT_RETURN(attach_count == expected_items); - - ret = kdbus_free(conn, offset); - ASSERT_RETURN(ret == 0); - - return 0; -} - -static int kdbus_test_bus_creator_info(struct kdbus_test_env *env) -{ - int ret; - int control_fd; - char *path; - char *busname; - char buspath[2048]; - char control_path[2048]; - uint64_t attach_flags_mask; - struct kdbus_conn *conn; - unsigned long expected_items = 0; - - snprintf(control_path, sizeof(control_path), - "%s/control", env->root); - - control_fd = open(control_path, O_RDWR); - ASSERT_RETURN(control_fd >= 0); - - busname = unique_name("test-peers-info-bus"); - ASSERT_RETURN(busname); - - /* - * Now the bus allows us to see all its KDBUS_ATTACH_* - * items - */ - ret = kdbus_create_bus(control_fd, busname, 0, - _KDBUS_ATTACH_ALL, &path); - ASSERT_RETURN(ret == 0); - - snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path); - - conn = __kdbus_hello(buspath, 0, 0, 0); - ASSERT_RETURN(conn); - - /* - * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY - */ - attach_flags_mask = _KDBUS_ATTACH_ANY; - - /* - * All flags will be returned except for: - * KDBUS_ITEM_TIMESTAMP - * KDBUS_ITEM_OWNED_NAME - * KDBUS_ITEM_CONN_DESCRIPTION - * - * An extra flags is always returned KDBUS_ITEM_MAKE_NAME - * which contains the bus name - */ - expected_items = KDBUS_TEST_ITEMS_SUM + KDBUS_ITEM_MAKE_NAME; - expected_items -= KDBUS_ITEM_TIMESTAMP + - KDBUS_ITEM_OWNED_NAME + - KDBUS_ITEM_CONN_DESCRIPTION; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - /* - * We should have: - * KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME - */ - expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + - KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - KDBUS_ATTACH_PIDS | - KDBUS_ATTACH_CREDS, - expected_items); - ASSERT_RETURN(ret == 0); - - /* KDBUS_ITEM_MAKE_NAME is always returned */ - expected_items = KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - 0, expected_items); - ASSERT_RETURN(ret == 0); - - /* - * Restrict kdbus system-wide mask to KDBUS_ATTACH_PIDS - */ - - attach_flags_mask = KDBUS_ATTACH_PIDS; - - /* - * We should have: - * KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME - */ - expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - - /* system-wide mask to 0 */ - attach_flags_mask = 0; - - /* we should only see: KDBUS_ITEM_MAKE_NAME */ - expected_items = KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - kdbus_conn_free(conn); - free(path); - free(busname); - close(control_fd); - - - /* - * A new bus that hides all its owner metadata - */ - - control_fd = open(control_path, O_RDWR); - ASSERT_RETURN(control_fd >= 0); - - busname = unique_name("test-peers-info-bus"); - ASSERT_RETURN(busname); - - ret = kdbus_create_bus(control_fd, busname, 0, 0, &path); - ASSERT_RETURN(ret == 0); - - snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path); - - conn = __kdbus_hello(buspath, 0, 0, 0); - ASSERT_RETURN(conn); - - /* - * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY - */ - attach_flags_mask = _KDBUS_ATTACH_ANY; - - /* - * We only get the KDBUS_ITEM_MAKE_NAME - */ - expected_items = KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - /* - * We still get only kdbus_ITEM_MAKE_NAME - */ - attach_flags_mask = 0; - expected_items = KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - kdbus_conn_free(conn); - free(path); - free(busname); - close(control_fd); - - - /* - * A new bus that shows only the PID and CREDS metadata - * of the bus owner. - */ - control_fd = open(control_path, O_RDWR); - ASSERT_RETURN(control_fd >= 0); - - busname = unique_name("test-peers-info-bus"); - ASSERT_RETURN(busname); - - ret = kdbus_create_bus(control_fd, busname, 0, - KDBUS_ATTACH_PIDS| - KDBUS_ATTACH_CREDS, &path); - ASSERT_RETURN(ret == 0); - - snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path); - - conn = __kdbus_hello(buspath, 0, 0, 0); - ASSERT_RETURN(conn); - - /* - * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY - */ - attach_flags_mask = _KDBUS_ATTACH_ANY; - - /* - * We should have: - * KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME - */ - expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + - KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - expected_items = KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - KDBUS_ATTACH_CREDS, - expected_items); - ASSERT_RETURN(ret == 0); - - /* KDBUS_ITEM_MAKE_NAME is always returned */ - expected_items = KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - 0, expected_items); - ASSERT_RETURN(ret == 0); - - /* - * Restrict kdbus system-wide mask to KDBUS_ATTACH_PIDS - */ - - attach_flags_mask = KDBUS_ATTACH_PIDS; - /* - * We should have: - * KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME - */ - expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - /* No KDBUS_ATTACH_CREDS */ - expected_items = KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - KDBUS_ATTACH_CREDS, - expected_items); - ASSERT_RETURN(ret == 0); - - /* system-wide mask to 0 */ - attach_flags_mask = 0; - - /* we should only see: KDBUS_ITEM_MAKE_NAME */ - expected_items = KDBUS_ITEM_MAKE_NAME; - ret = kdbus_cmp_bus_creator_metadata(env, conn, - attach_flags_mask, - _KDBUS_ATTACH_ALL, - expected_items); - ASSERT_RETURN(ret == 0); - - - kdbus_conn_free(conn); - free(path); - free(busname); - close(control_fd); - - return 0; -} - -int kdbus_test_attach_flags(struct kdbus_test_env *env) -{ - int ret; - uint64_t flags_mask; - uint64_t old_kdbus_flags_mask; - - /* We need CAP_DAC_OVERRIDE to overwrite the kdbus mask */ - ret = test_is_capable(CAP_DAC_OVERRIDE, -1); - ASSERT_RETURN(ret >= 0); - - /* no enough privileges, SKIP test */ - if (!ret) - return TEST_SKIP; - - /* - * We need to be able to write to - * "/sys/module/kdbus/parameters/attach_flags_mask" - * perhaps we are unprvileged/privileged in its userns - */ - ret = access(env->mask_param_path, W_OK); - if (ret < 0) { - kdbus_printf("--- access() '%s' failed: %d (%m)\n", - env->mask_param_path, -errno); - return TEST_SKIP; - } - - ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path, - &old_kdbus_flags_mask); - ASSERT_RETURN(ret == 0); - - /* setup the right KDBUS_TEST_ITEMS_SUM */ - if (!config_auditsyscall_is_enabled()) - KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_AUDIT; - - if (!config_cgroups_is_enabled()) - KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_CGROUP; - - if (!config_security_is_enabled()) - KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_SECLABEL; - - /* - * Test the connection creation attach flags - */ - ret = kdbus_test_peers_creation(env); - /* Restore previous kdbus mask */ - kdbus_sysfs_set_parameter_mask(env->mask_param_path, - old_kdbus_flags_mask); - ASSERT_RETURN(ret == 0); - - /* - * Test the CONN_INFO attach flags - */ - ret = kdbus_test_peers_info(env); - /* Restore previous kdbus mask */ - kdbus_sysfs_set_parameter_mask(env->mask_param_path, - old_kdbus_flags_mask); - ASSERT_RETURN(ret == 0); - - /* - * Test the Bus creator info and its attach flags - */ - ret = kdbus_test_bus_creator_info(env); - /* Restore previous kdbus mask */ - kdbus_sysfs_set_parameter_mask(env->mask_param_path, - old_kdbus_flags_mask); - ASSERT_RETURN(ret == 0); - - ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path, - &flags_mask); - ASSERT_RETURN(ret == 0 && old_kdbus_flags_mask == flags_mask); - - return TEST_OK; -} diff --git a/tools/testing/selftests/kdbus/test-benchmark.c b/tools/testing/selftests/kdbus/test-benchmark.c index 8a9744b..e53ebb5c 100644 --- a/tools/testing/selftests/kdbus/test-benchmark.c +++ b/tools/testing/selftests/kdbus/test-benchmark.c @@ -92,7 +92,7 @@ static void add_stats(uint64_t prev) stats.latency_high = diff; } -static int setup_simple_kdbus_msg(struct kdbus_conn *conn, +static wur int setup_simple_kdbus_msg(struct kdbus_conn *conn, uint64_t dst_id, struct kdbus_msg **msg_out) { @@ -103,8 +103,8 @@ static int setup_simple_kdbus_msg(struct kdbus_conn *conn, size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); - msg = malloc(size); - ASSERT_RETURN_VAL(msg, -ENOMEM); + msg = alloc(size); + ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM); memset(msg, 0, size); msg->size = size; @@ -125,7 +125,7 @@ static int setup_simple_kdbus_msg(struct kdbus_conn *conn, return 0; } -static int setup_memfd_kdbus_msg(struct kdbus_conn *conn, +static wur int setup_memfd_kdbus_msg(struct kdbus_conn *conn, uint64_t dst_id, off_t *memfd_item_offset, struct kdbus_msg **msg_out) @@ -138,8 +138,8 @@ static int setup_memfd_kdbus_msg(struct kdbus_conn *conn, size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); - msg = malloc(size); - ASSERT_RETURN_VAL(msg, -ENOMEM); + msg = alloc(size); + ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM); memset(msg, 0, size); msg->size = size; @@ -165,9 +165,8 @@ static int setup_memfd_kdbus_msg(struct kdbus_conn *conn, return 0; } -static int -send_echo_request(struct kdbus_conn *conn, uint64_t dst_id, - void *kdbus_msg, off_t memfd_item_offset) +static wur int +send_echo_request(struct kdbus_conn *conn, void *kdbus_msg, off_t memfd_item_offset) { struct kdbus_cmd_send cmd = {}; int memfd = -1; @@ -177,13 +176,11 @@ send_echo_request(struct kdbus_conn *conn, uint64_t dst_id, uint64_t now_ns = now(CLOCK_THREAD_CPUTIME_ID); struct kdbus_item *item = memfd_item_offset + kdbus_msg; memfd = sys_memfd_create("memfd-name", 0); - ASSERT_RETURN_VAL(memfd >= 0, memfd); + ASSERT_RETURN_VAL(memfd,>=,0, memfd); - ret = write(memfd, &now_ns, sizeof(now_ns)); - ASSERT_RETURN_VAL(ret == sizeof(now_ns), -EAGAIN); + ASSERT_RETURN_VAL(write(memfd, &now_ns, sizeof(now_ns)),==,(typeof(write(memfd, &now_ns, sizeof(now_ns))))sizeof(now_ns), -EAGAIN); - ret = sys_memfd_seal_set(memfd); - ASSERT_RETURN_VAL(ret == 0, -errno); + ASSERT_RETURN_VAL(sys_memfd_seal_set(memfd),==,0, -errno); item->memfd.fd = memfd; } @@ -192,14 +189,15 @@ send_echo_request(struct kdbus_conn *conn, uint64_t dst_id, cmd.msg_address = (uintptr_t)kdbus_msg; ret = kdbus_cmd_send(conn->fd, &cmd); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); - close(memfd); + if (-1 != memfd) + CLOSE(memfd); return 0; } -static int +static wur int handle_echo_reply(struct kdbus_conn *conn, uint64_t send_ns) { int ret; @@ -212,7 +210,7 @@ handle_echo_reply(struct kdbus_conn *conn, uint64_t send_ns) if (ret == -EAGAIN) return ret; - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); if (!use_memfd) goto out; @@ -226,13 +224,14 @@ handle_echo_reply(struct kdbus_conn *conn, uint64_t send_ns) buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_PRIVATE, item->memfd.fd, 0); - ASSERT_RETURN_VAL(buf != MAP_FAILED, -EINVAL); - ASSERT_RETURN_VAL(item->memfd.size == sizeof(uint64_t), - -EINVAL); + if (MAP_FAILED == buf) + print("memfdfail_item->memfd.size(%llu)_item->memfd.fd(%d)", (unsigned long long)item->memfd.size, item->memfd.fd); + ASSERT_RETURN_VAL(buf,!=,MAP_FAILED, -EINVAL); + ASSERT_RETURN_VAL(item->memfd.size,==,sizeof(uint64_t), -EINVAL); add_stats(*(uint64_t*)buf); munmap(buf, item->memfd.size); - close(item->memfd.fd); + CLOSE(item->memfd.fd); has_memfd = true; break; } @@ -248,12 +247,12 @@ out: add_stats(send_ns); ret = kdbus_free(conn, recv.msg.offset); - ASSERT_RETURN_VAL(ret == 0, -errno); + ASSERT_RETURN_VAL(ret,==,0, -errno); return 0; } -static int benchmark(struct kdbus_test_env *env) +static wur int benchmark(struct kdbus_test_env *env) { static char buf[sizeof(stress_payload)]; struct kdbus_msg *kdbus_msg = NULL; @@ -273,60 +272,45 @@ static int benchmark(struct kdbus_test_env *env) /* setup kdbus pair */ conn_a = kdbus_hello(env->buspath, 0, NULL, 0); + ASSERT_NONZERO(conn_a); conn_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_a && conn_b); + ASSERT_NONZERO(conn_b); - ret = kdbus_add_match_empty(conn_a); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn_a)); - ret = kdbus_add_match_empty(conn_b); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn_b)); - ret = kdbus_name_acquire(conn_a, SERVICE_NAME, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn_a, SERVICE_NAME, NULL)); - if (attach_none) { - ret = kdbus_conn_update_attach_flags(conn_a, - _KDBUS_ATTACH_ALL, - 0); - ASSERT_RETURN(ret == 0); - } + if (attach_none) + ASSERT_ZERO(kdbus_conn_update_attach_flags(conn_a, _KDBUS_ATTACH_ALL, 0)); /* setup UDS pair */ - ret = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0, uds); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0, uds)); /* setup a kdbus msg now */ - if (use_memfd) { - ret = setup_memfd_kdbus_msg(conn_b, conn_a->id, - &memfd_cached_offset, - &kdbus_msg); - ASSERT_RETURN(ret == 0); - } else { - ret = setup_simple_kdbus_msg(conn_b, conn_a->id, &kdbus_msg); - ASSERT_RETURN(ret == 0); - } + if (use_memfd) + ASSERT_ZERO(setup_memfd_kdbus_msg(conn_b, conn_a->id, &memfd_cached_offset, &kdbus_msg)); + else + ASSERT_ZERO(setup_simple_kdbus_msg(conn_b, conn_a->id, &kdbus_msg)); /* start benchmark */ kdbus_printf("-- entering poll loop ...\n"); + ASSERT_NO_PENDING(conn_a); + do { /* run kdbus benchmark */ fds[0].fd = conn_a->fd; fds[1].fd = conn_b->fd; - /* cancel any pending message */ - handle_echo_reply(conn_a, 0); - start = now(CLOCK_THREAD_CPUTIME_ID); reset_stats(); send_ns = now(CLOCK_THREAD_CPUTIME_ID); - ret = send_echo_request(conn_b, conn_a->id, - kdbus_msg, memfd_cached_offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_echo_request(conn_b, kdbus_msg, memfd_cached_offset)); while (1) { unsigned int nfds = sizeof(fds) / sizeof(fds[0]); @@ -342,14 +326,10 @@ static int benchmark(struct kdbus_test_env *env) break; if (fds[0].revents & POLLIN) { - ret = handle_echo_reply(conn_a, send_ns); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(handle_echo_reply(conn_a, send_ns)); send_ns = now(CLOCK_THREAD_CPUTIME_ID); - ret = send_echo_request(conn_b, conn_a->id, - kdbus_msg, - memfd_cached_offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_echo_request(conn_b, kdbus_msg, memfd_cached_offset)); } now_ns = now(CLOCK_THREAD_CPUTIME_ID); @@ -358,6 +338,7 @@ static int benchmark(struct kdbus_test_env *env) start = now_ns; dump_stats(false); + ASSERT_ZERO(handle_echo_reply(conn_a, send_ns)); /* purge last message to prevent leaks */ break; } } @@ -370,15 +351,14 @@ static int benchmark(struct kdbus_test_env *env) fds[0].fd = uds[0]; fds[1].fd = uds[1]; - /* cancel any pendign message */ - read(uds[1], buf, sizeof(buf)); + /* cancel any pending message */ + UNUSED(read(uds[1], buf, sizeof(buf))); start = now(CLOCK_THREAD_CPUTIME_ID); reset_stats(); send_ns = now(CLOCK_THREAD_CPUTIME_ID); - ret = write(uds[0], stress_payload, sizeof(stress_payload)); - ASSERT_RETURN(ret == sizeof(stress_payload)); + ASSERT_RETURN((typeof(write(uds[0], stress_payload, sizeof(stress_payload))))sizeof(stress_payload),==,write(uds[0], stress_payload, sizeof(stress_payload))); while (1) { unsigned int nfds = sizeof(fds) / sizeof(fds[0]); @@ -394,14 +374,12 @@ static int benchmark(struct kdbus_test_env *env) break; if (fds[1].revents & POLLIN) { - ret = read(uds[1], buf, sizeof(buf)); - ASSERT_RETURN(ret == sizeof(buf)); + ASSERT_RETURN((typeof(read(uds[1], buf, sizeof(buf))))sizeof(buf),==,read(uds[1], buf, sizeof(buf))); add_stats(send_ns); send_ns = now(CLOCK_THREAD_CPUTIME_ID); - ret = write(uds[0], buf, sizeof(buf)); - ASSERT_RETURN(ret == sizeof(buf)); + ASSERT_RETURN((typeof(write(uds[0], buf, sizeof(buf))))sizeof(buf),==,write(uds[0], buf, sizeof(buf))); } now_ns = now(CLOCK_THREAD_CPUTIME_ID); @@ -426,7 +404,7 @@ static int benchmark(struct kdbus_test_env *env) return (stats.count > 1) ? TEST_OK : TEST_ERR; } -int kdbus_test_benchmark(struct kdbus_test_env *env) +wur int kdbus_test_benchmark(struct kdbus_test_env *env) { use_memfd = true; attach_none = false; @@ -434,7 +412,7 @@ int kdbus_test_benchmark(struct kdbus_test_env *env) return benchmark(env); } -int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env) +wur int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env) { use_memfd = false; attach_none = false; @@ -442,7 +420,7 @@ int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env) return benchmark(env); } -int kdbus_test_benchmark_uds(struct kdbus_test_env *env) +wur int kdbus_test_benchmark_uds(struct kdbus_test_env *env) { use_memfd = false; attach_none = true; diff --git a/tools/testing/selftests/kdbus/test-bus.c b/tools/testing/selftests/kdbus/test-bus.c index 762fb30..85fb222 100644 --- a/tools/testing/selftests/kdbus/test-bus.c +++ b/tools/testing/selftests/kdbus/test-bus.c @@ -16,7 +16,7 @@ #include "kdbus-enum.h" #include "kdbus-test.h" -static struct kdbus_item *kdbus_get_item(struct kdbus_info *info, +static wur struct kdbus_item *kdbus_get_item(struct kdbus_info *info, uint64_t type) { struct kdbus_item *item; @@ -28,7 +28,7 @@ static struct kdbus_item *kdbus_get_item(struct kdbus_info *info, return NULL; } -static int test_bus_creator_info(const char *bus_path) +static wur int test_bus_creator_info(const char *bus_path) { int ret; uint64_t offset; @@ -39,35 +39,34 @@ static int test_bus_creator_info(const char *bus_path) /* extract the bus-name from @bus_path */ tmp = strdup(bus_path); - ASSERT_RETURN(tmp); + ASSERT_NONZERO(tmp); busname = strrchr(tmp, '/'); - ASSERT_RETURN(busname); + ASSERT_NONZERO(busname); *busname = 0; busname = strrchr(tmp, '/'); - ASSERT_RETURN(busname); + ASSERT_NONZERO(busname); ++busname; conn = kdbus_hello(bus_path, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn); - ret = kdbus_bus_creator_info(conn, _KDBUS_ATTACH_ALL, &offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_bus_creator_info(conn, _KDBUS_ATTACH_ALL, &offset)); info = (struct kdbus_info *)(conn->buf + offset); item = kdbus_get_item(info, KDBUS_ITEM_MAKE_NAME); - ASSERT_RETURN(item); - ASSERT_RETURN(!strcmp(item->str, busname)); + ASSERT_NONZERO(item); + ASSERT_ZERO(strcmp(item->str, busname)); ret = kdbus_free(conn, offset); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); free(tmp); kdbus_conn_free(conn); return 0; } -int kdbus_test_bus_make(struct kdbus_test_env *env) +wur int kdbus_test_bus_make(struct kdbus_test_env *env) { struct { struct kdbus_cmd cmd; @@ -85,18 +84,18 @@ int kdbus_test_bus_make(struct kdbus_test_env *env) char name[64]; } bus_make; char s[PATH_MAX], *name; - int ret, control_fd2; + int control_fd2; uid_t uid; name = unique_name(""); - ASSERT_RETURN(name); + ASSERT_NONZERO(name); snprintf(s, sizeof(s), "%s/control", env->root); env->control_fd = open(s, O_RDWR|O_CLOEXEC); - ASSERT_RETURN(env->control_fd >= 0); + ASSERT_RETURN(env->control_fd,>=,0); control_fd2 = open(s, O_RDWR|O_CLOEXEC); - ASSERT_RETURN(control_fd2 >= 0); + ASSERT_RETURN(control_fd2,>=,0); memset(&bus_make, 0, sizeof(bus_make)); @@ -114,41 +113,35 @@ int kdbus_test_bus_make(struct kdbus_test_env *env) bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.cmd.size = sizeof(struct kdbus_cmd) + sizeof(bus_make.bs) + bus_make.n_size; - ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd)); /* non alphanumeric character */ snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah@123", uid); bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.cmd.size = sizeof(struct kdbus_cmd) + sizeof(bus_make.bs) + bus_make.n_size; - ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd)); /* '-' at the end */ snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah-", uid); bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.cmd.size = sizeof(struct kdbus_cmd) + sizeof(bus_make.bs) + bus_make.n_size; - ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd)); /* create a new bus */ snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-1", uid, name); bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.cmd.size = sizeof(struct kdbus_cmd) + sizeof(bus_make.bs) + bus_make.n_size; - ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd)); - ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd); - ASSERT_RETURN(ret == -EEXIST); + ASSERT_RETURN(-EEXIST,==,kdbus_cmd_bus_make(control_fd2, &bus_make.cmd)); snprintf(s, sizeof(s), "%s/%u-%s-1/bus", env->root, uid, name); - ASSERT_RETURN(access(s, F_OK) == 0); + ASSERT_ZERO(access(s, F_OK)); - ret = test_bus_creator_info(s); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_bus_creator_info(s)); /* can't use the same fd for bus make twice, even though a different * bus name is used @@ -157,18 +150,16 @@ int kdbus_test_bus_make(struct kdbus_test_env *env) bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.cmd.size = sizeof(struct kdbus_cmd) + sizeof(bus_make.bs) + bus_make.n_size; - ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd); - ASSERT_RETURN(ret == -EBADFD); + ASSERT_RETURN(-EBADFD,==,kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd)); /* create a new bus, with different fd and different bus name */ snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-2", uid, name); bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.cmd.size = sizeof(struct kdbus_cmd) + sizeof(bus_make.bs) + bus_make.n_size; - ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_bus_make(control_fd2, &bus_make.cmd)); - close(control_fd2); + CLOSE(control_fd2); free(name); return TEST_OK; diff --git a/tools/testing/selftests/kdbus/test-chat.c b/tools/testing/selftests/kdbus/test-chat.c index e19f595..fe6eea7 100644 --- a/tools/testing/selftests/kdbus/test-chat.c +++ b/tools/testing/selftests/kdbus/test-chat.c @@ -15,7 +15,7 @@ #include "kdbus-util.h" #include "kdbus-enum.h" -int kdbus_test_chat(struct kdbus_test_env *env) +wur int kdbus_test_chat(struct kdbus_test_env *env) { int ret, cookie; struct kdbus_conn *conn_a, *conn_b; @@ -24,48 +24,36 @@ int kdbus_test_chat(struct kdbus_test_env *env) int count; conn_a = kdbus_hello(env->buspath, 0, NULL, 0); + ASSERT_NONZERO(conn_a); conn_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_a && conn_b); + ASSERT_NONZERO(conn_b); flags = KDBUS_NAME_ALLOW_REPLACEMENT; - ret = kdbus_name_acquire(conn_a, "foo.bar.test", &flags); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn_a, "foo.bar.test", &flags)); - ret = kdbus_name_acquire(conn_a, "foo.bar.baz", NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn_a, "foo.bar.baz", NULL)); flags = KDBUS_NAME_QUEUE; - ret = kdbus_name_acquire(conn_b, "foo.bar.baz", &flags); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn_b, "foo.bar.baz", &flags)); - ret = kdbus_name_acquire(conn_a, "foo.bar.double", NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn_a, "foo.bar.double", NULL)); - ret = kdbus_name_acquire(conn_a, "foo.bar.double", NULL); - ASSERT_RETURN(ret == -EALREADY); + flags = 0; + ASSERT_ZERO(kdbus_name_acquire(conn_a, "foo.bar.double", &flags)); + ASSERT_ZERO(flags & KDBUS_NAME_ACQUIRED); - ret = kdbus_name_release(conn_a, "foo.bar.double"); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_release(conn_a, "foo.bar.double")); - ret = kdbus_name_release(conn_a, "foo.bar.double"); - ASSERT_RETURN(ret == -ESRCH); + ASSERT_RETURN(-ESRCH,==,kdbus_name_release(conn_a, "foo.bar.double")); - ret = kdbus_list(conn_b, KDBUS_LIST_UNIQUE | - KDBUS_LIST_NAMES | - KDBUS_LIST_QUEUED | - KDBUS_LIST_ACTIVATORS); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_list(conn_b, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES | KDBUS_LIST_QUEUED | KDBUS_LIST_ACTIVATORS)); - ret = kdbus_add_match_empty(conn_a); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn_a)); - ret = kdbus_add_match_empty(conn_b); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn_b)); cookie = 0; - ret = kdbus_msg_send(conn_b, NULL, 0xc0000000 | cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn_b, NULL, 0xc0000000 | cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); fds[0].fd = conn_a->fd; fds[1].fd = conn_b->fd; @@ -81,34 +69,22 @@ int kdbus_test_chat(struct kdbus_test_env *env) } ret = poll(fds, nfds, 3000); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); if (fds[0].revents & POLLIN) { - if (count > 2) - kdbus_name_release(conn_a, "foo.bar.baz"); - - ret = kdbus_msg_recv(conn_a, NULL, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(conn_a, NULL, - 0xc0000000 | cookie++, - 0, 0, 0, conn_b->id, 0, NULL); - ASSERT_RETURN(ret == 0); + if (count == 3) + ASSERT_ZERO(kdbus_name_release(conn_a, "foo.bar.baz")); + + ASSERT_ZERO(kdbus_msg_recv(conn_a, NULL, NULL)); + ASSERT_ZERO(kdbus_msg_send(conn_a, NULL, 0xc0000000 | cookie++, 0, 0, 0, conn_b->id)); } if (fds[1].revents & POLLIN) { - ret = kdbus_msg_recv(conn_b, NULL, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(conn_b, NULL, - 0xc0000000 | cookie++, - 0, 0, 0, conn_a->id, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(conn_b, NULL, NULL)); + ASSERT_ZERO(kdbus_msg_send(conn_b, NULL, 0xc0000000 | cookie++, 0, 0, 0, conn_a->id)); } - ret = kdbus_list(conn_b, KDBUS_LIST_UNIQUE | - KDBUS_LIST_NAMES | - KDBUS_LIST_QUEUED | - KDBUS_LIST_ACTIVATORS); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_list(conn_b, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES | KDBUS_LIST_QUEUED | KDBUS_LIST_ACTIVATORS)); if (count > 10) break; diff --git a/tools/testing/selftests/kdbus/test-connection.c b/tools/testing/selftests/kdbus/test-connection.c index 7afb76f..73a3096 100644 --- a/tools/testing/selftests/kdbus/test-connection.c +++ b/tools/testing/selftests/kdbus/test-connection.c @@ -20,16 +20,16 @@ #include "kdbus-enum.h" #include "kdbus-test.h" -int kdbus_test_hello(struct kdbus_test_env *env) +wur int kdbus_test_hello(struct kdbus_test_env *env) { struct kdbus_cmd_free cmd_free = {}; struct kdbus_cmd_hello hello; - int fd, ret; + int fd; memset(&hello, 0, sizeof(hello)); fd = open(env->buspath, O_RDWR|O_CLOEXEC); - ASSERT_RETURN(fd >= 0); + ASSERT_RETURN(fd,>=,0); hello.flags = KDBUS_HELLO_ACCEPT_FD; hello.attach_flags_send = _KDBUS_ATTACH_ALL; @@ -38,116 +38,89 @@ int kdbus_test_hello(struct kdbus_test_env *env) hello.pool_size = POOL_SIZE; /* an unaligned hello must result in -EFAULT */ - ret = kdbus_cmd_hello(fd, (struct kdbus_cmd_hello *) ((char *) &hello + 1)); - ASSERT_RETURN(ret == -EFAULT); + ASSERT_RETURN(-EFAULT,==,kdbus_cmd_hello(fd, (struct kdbus_cmd_hello *) ((char *) &hello + 1))); /* a size of 0 must return EMSGSIZE */ hello.size = 1; hello.flags = KDBUS_HELLO_ACCEPT_FD; hello.attach_flags_send = _KDBUS_ATTACH_ALL; - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_hello(fd, &hello)); hello.size = sizeof(struct kdbus_cmd_hello); /* check faulty flags */ hello.flags = 1ULL << 32; hello.attach_flags_send = _KDBUS_ATTACH_ALL; - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_hello(fd, &hello)); /* check for faulty pool sizes */ hello.pool_size = 0; hello.flags = KDBUS_HELLO_ACCEPT_FD; hello.attach_flags_send = _KDBUS_ATTACH_ALL; - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_hello(fd, &hello)); hello.pool_size = 4097; hello.attach_flags_send = _KDBUS_ATTACH_ALL; - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_hello(fd, &hello)); hello.pool_size = POOL_SIZE; - /* - * The connection created by the core requires ALL meta flags - * to be sent. An attempt to send less than that should result in - * -ECONNREFUSED. - */ - hello.attach_flags_send = _KDBUS_ATTACH_ALL & ~KDBUS_ATTACH_TIMESTAMP; - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == -ECONNREFUSED); - hello.attach_flags_send = _KDBUS_ATTACH_ALL; hello.offset = (__u64)-1; /* success test */ - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_hello(fd, &hello)); /* The kernel should have returned some items */ - ASSERT_RETURN(hello.offset != (__u64)-1); + ASSERT_RETURN(hello.offset,!=,(__u64)-1); cmd_free.size = sizeof(cmd_free); cmd_free.offset = hello.offset; - ret = kdbus_cmd_free(fd, &cmd_free); - ASSERT_RETURN(ret >= 0); + ASSERT_ZERO(kdbus_cmd_free(fd, &cmd_free)); - close(fd); + CLOSE(fd); fd = open(env->buspath, O_RDWR|O_CLOEXEC); - ASSERT_RETURN(fd >= 0); + ASSERT_RETURN(fd,>=,0); /* no ACTIVATOR flag without a name */ hello.flags = KDBUS_HELLO_ACTIVATOR; - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_hello(fd, &hello)); - close(fd); + CLOSE(fd); return TEST_OK; } -int kdbus_test_byebye(struct kdbus_test_env *env) +wur int kdbus_test_byebye(struct kdbus_test_env *env) { struct kdbus_conn *conn; struct kdbus_cmd_recv cmd_recv = { .size = sizeof(cmd_recv) }; struct kdbus_cmd cmd_byebye = { .size = sizeof(cmd_byebye) }; - int ret; /* create a 2nd connection */ conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn); - ret = kdbus_add_match_empty(conn); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn)); - ret = kdbus_add_match_empty(env->conn); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(env->conn)); /* send over 1st connection */ - ret = kdbus_msg_send(env->conn, NULL, 0, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, 0, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); /* say byebye on the 2nd, which must fail */ - ret = kdbus_cmd_byebye(conn->fd, &cmd_byebye); - ASSERT_RETURN(ret == -EBUSY); + ASSERT_RETURN(-EBUSY,==,kdbus_cmd_byebye(conn->fd, &cmd_byebye)); /* receive the message */ - ret = kdbus_cmd_recv(conn->fd, &cmd_recv); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_recv(conn->fd, &cmd_recv)); - ret = kdbus_free(conn, cmd_recv.msg.offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_free(conn, cmd_recv.msg.offset)); /* and try again */ - ret = kdbus_cmd_byebye(conn->fd, &cmd_byebye); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_byebye(conn->fd, &cmd_byebye)); /* a 2nd try should result in -ECONNRESET */ - ret = kdbus_cmd_byebye(conn->fd, &cmd_byebye); - ASSERT_RETURN(ret == -ECONNRESET); + ASSERT_RETURN(-ECONNRESET,==,kdbus_cmd_byebye(conn->fd, &cmd_byebye)); kdbus_conn_free(conn); @@ -155,7 +128,7 @@ int kdbus_test_byebye(struct kdbus_test_env *env) } /* Get only the first item */ -static struct kdbus_item *kdbus_get_item(struct kdbus_info *info, +static wur struct kdbus_item *kdbus_get_item(struct kdbus_info *info, uint64_t type) { struct kdbus_item *item; @@ -167,7 +140,7 @@ static struct kdbus_item *kdbus_get_item(struct kdbus_info *info, return NULL; } -static unsigned int kdbus_count_item(struct kdbus_info *info, +static wur unsigned int kdbus_count_item(struct kdbus_info *info, uint64_t type) { unsigned int i = 0; @@ -180,18 +153,14 @@ static unsigned int kdbus_count_item(struct kdbus_info *info, return i; } -static int kdbus_fuzz_conn_info(struct kdbus_test_env *env, int capable) +static wur int kdbus_fuzz_conn_info(struct kdbus_test_env *env, int capable) { - int ret; unsigned int cnt = 0; uint64_t offset = 0; - uint64_t kdbus_flags_mask; struct kdbus_info *info; struct kdbus_conn *conn; struct kdbus_conn *privileged; const struct kdbus_item *item; - uint64_t valid_flags_set; - uint64_t invalid_flags_set; uint64_t valid_flags = KDBUS_ATTACH_NAMES | KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS | @@ -227,138 +196,114 @@ static int kdbus_fuzz_conn_info(struct kdbus_test_env *env, int capable) .ppid = getppid(), }; - ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path, - &kdbus_flags_mask); - ASSERT_RETURN(ret == 0); - - valid_flags_set = valid_flags & kdbus_flags_mask; - invalid_flags_set = invalid_flags & kdbus_flags_mask; - - ret = kdbus_conn_info(env->conn, env->conn->id, NULL, - valid_flags, &offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(env->conn, env->conn->id, NULL, valid_flags, &offset)); info = (struct kdbus_info *)(env->conn->buf + offset); - ASSERT_RETURN(info->id == env->conn->id); + ASSERT_RETURN(info->id,==,env->conn->id); /* We do not have any well-known name */ item = kdbus_get_item(info, KDBUS_ITEM_NAME); - ASSERT_RETURN(item == NULL); + ASSERT_ZERO(item); item = kdbus_get_item(info, KDBUS_ITEM_CONN_DESCRIPTION); - if (valid_flags_set & KDBUS_ATTACH_CONN_DESCRIPTION) { - ASSERT_RETURN(item); - } else { - ASSERT_RETURN(item == NULL); - } + if (valid_flags & KDBUS_ATTACH_CONN_DESCRIPTION) + ASSERT_NONZERO(item); + else + ASSERT_ZERO(item); - kdbus_free(env->conn, offset); + ASSERT_ZERO(kdbus_free(env->conn, offset)); conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn); privileged = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(privileged); + ASSERT_NONZERO(privileged); - ret = kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset)); info = (struct kdbus_info *)(conn->buf + offset); - ASSERT_RETURN(info->id == conn->id); + ASSERT_RETURN(info->id,==,conn->id); /* We do not have any well-known name */ item = kdbus_get_item(info, KDBUS_ITEM_NAME); - ASSERT_RETURN(item == NULL); + ASSERT_ZERO(item); cnt = kdbus_count_item(info, KDBUS_ITEM_CREDS); - if (valid_flags_set & KDBUS_ATTACH_CREDS) { - ASSERT_RETURN(cnt == 1); + if (valid_flags & KDBUS_ATTACH_CREDS) { + ASSERT_RETURN(cnt,==,1U); item = kdbus_get_item(info, KDBUS_ITEM_CREDS); - ASSERT_RETURN(item); + ASSERT_NONZERO(item); /* Compare received items with cached creds */ - ASSERT_RETURN(memcmp(&item->creds, &cached_creds, - sizeof(struct kdbus_creds)) == 0); - } else { - ASSERT_RETURN(cnt == 0); - } + ASSERT_ZERO(memcmp(&item->creds, &cached_creds, sizeof(struct kdbus_creds))); + } else + ASSERT_ZERO(cnt); item = kdbus_get_item(info, KDBUS_ITEM_PIDS); - if (valid_flags_set & KDBUS_ATTACH_PIDS) { - ASSERT_RETURN(item); + if (valid_flags & KDBUS_ATTACH_PIDS) { + ASSERT_NONZERO(item); /* Compare item->pids with cached PIDs */ - ASSERT_RETURN(item->pids.pid == cached_pids.pid && - item->pids.tid == cached_pids.tid && - item->pids.ppid == cached_pids.ppid); - } else { - ASSERT_RETURN(item == NULL); - } + ASSERT_RETURN(item->pids.pid,==,cached_pids.pid); + ASSERT_RETURN(item->pids.tid,==,cached_pids.tid); + ASSERT_RETURN(item->pids.ppid,==,cached_pids.ppid); + } else + ASSERT_ZERO(item); /* We did not request KDBUS_ITEM_CAPS */ item = kdbus_get_item(info, KDBUS_ITEM_CAPS); - ASSERT_RETURN(item == NULL); + ASSERT_ZERO(item); - kdbus_free(conn, offset); + ASSERT_ZERO(kdbus_free(conn, offset)); - ret = kdbus_name_acquire(conn, "com.example.a", NULL); - ASSERT_RETURN(ret >= 0); + ASSERT_ZERO(kdbus_name_acquire(conn, "com.example.a", NULL)); - ret = kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset)); info = (struct kdbus_info *)(conn->buf + offset); - ASSERT_RETURN(info->id == conn->id); + ASSERT_RETURN(info->id,==,conn->id); item = kdbus_get_item(info, KDBUS_ITEM_OWNED_NAME); - if (valid_flags_set & KDBUS_ATTACH_NAMES) { - ASSERT_RETURN(item && !strcmp(item->name.name, "com.example.a")); - } else { - ASSERT_RETURN(item == NULL); - } + if (valid_flags & KDBUS_ATTACH_NAMES) { + ASSERT_NONZERO(item); + ASSERT_ZERO(strcmp(item->name.name, "com.example.a")); + } else + ASSERT_ZERO(item); - kdbus_free(conn, offset); + ASSERT_ZERO(kdbus_free(conn, offset)); - ret = kdbus_conn_info(conn, 0, "com.example.a", valid_flags, &offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(conn, 0, "com.example.a", valid_flags, &offset)); info = (struct kdbus_info *)(conn->buf + offset); - ASSERT_RETURN(info->id == conn->id); + ASSERT_RETURN(info->id,==,conn->id); - kdbus_free(conn, offset); + ASSERT_ZERO(kdbus_free(conn, offset)); /* does not have the necessary caps to drop to unprivileged */ if (!capable) goto continue_test; - ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ - ret = kdbus_conn_info(conn, conn->id, NULL, - valid_flags, &offset); - ASSERT_EXIT(ret == 0); + RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ + ASSERT_EXIT_ZERO(kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset)); info = (struct kdbus_info *)(conn->buf + offset); - ASSERT_EXIT(info->id == conn->id); + ASSERT_EXIT(info->id,==,conn->id); - if (valid_flags_set & KDBUS_ATTACH_NAMES) { - item = kdbus_get_item(info, KDBUS_ITEM_OWNED_NAME); - ASSERT_EXIT(item && - strcmp(item->name.name, - "com.example.a") == 0); + if (valid_flags & KDBUS_ATTACH_NAMES) { + ASSERT_EXIT_NONZERO(item = kdbus_get_item(info, KDBUS_ITEM_OWNED_NAME)); + ASSERT_EXIT_ZERO(strcmp(item->name.name, "com.example.a")); } - if (valid_flags_set & KDBUS_ATTACH_CREDS) { - item = kdbus_get_item(info, KDBUS_ITEM_CREDS); - ASSERT_EXIT(item); + if (valid_flags & KDBUS_ATTACH_CREDS) { + ASSERT_EXIT_NONZERO(item = kdbus_get_item(info, KDBUS_ITEM_CREDS)); /* Compare received items with cached creds */ - ASSERT_EXIT(memcmp(&item->creds, &cached_creds, - sizeof(struct kdbus_creds)) == 0); + ASSERT_EXIT_ZERO(memcmp(&item->creds, &cached_creds, sizeof(struct kdbus_creds))); } - if (valid_flags_set & KDBUS_ATTACH_PIDS) { - item = kdbus_get_item(info, KDBUS_ITEM_PIDS); - ASSERT_EXIT(item); + if (valid_flags & KDBUS_ATTACH_PIDS) { + ASSERT_EXIT_NONZERO(item = kdbus_get_item(info, KDBUS_ITEM_PIDS)); /* * Compare item->pids with cached pids of @@ -366,98 +311,83 @@ static int kdbus_fuzz_conn_info(struct kdbus_test_env *env, int capable) * * cmd_info will always return cached pids. */ - ASSERT_EXIT(item->pids.pid == cached_pids.pid && - item->pids.tid == cached_pids.tid); + ASSERT_EXIT(item->pids.pid,==,cached_pids.pid); + ASSERT_EXIT(item->pids.tid,==,cached_pids.tid); } - kdbus_free(conn, offset); + ASSERT_ZERO(kdbus_free(conn, offset)); /* * Use invalid_flags and make sure that userspace * do not play with us. */ - ret = kdbus_conn_info(conn, conn->id, NULL, - invalid_flags, &offset); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_conn_info(conn, conn->id, NULL, invalid_flags, &offset)); /* * Make sure that we return only one creds item and * it points to the cached creds. */ cnt = kdbus_count_item(info, KDBUS_ITEM_CREDS); - if (invalid_flags_set & KDBUS_ATTACH_CREDS) { - ASSERT_EXIT(cnt == 1); + if (invalid_flags & KDBUS_ATTACH_CREDS) { + ASSERT_EXIT(cnt,==,1U); - item = kdbus_get_item(info, KDBUS_ITEM_CREDS); - ASSERT_EXIT(item); + ASSERT_EXIT_NONZERO(item = kdbus_get_item(info, KDBUS_ITEM_CREDS)); /* Compare received items with cached creds */ - ASSERT_EXIT(memcmp(&item->creds, &cached_creds, - sizeof(struct kdbus_creds)) == 0); - } else { - ASSERT_EXIT(cnt == 0); - } + ASSERT_EXIT_ZERO(memcmp(&item->creds, &cached_creds, sizeof(struct kdbus_creds))); + } else + ASSERT_EXIT_ZERO(cnt); - if (invalid_flags_set & KDBUS_ATTACH_PIDS) { + if (invalid_flags & KDBUS_ATTACH_PIDS) { cnt = kdbus_count_item(info, KDBUS_ITEM_PIDS); - ASSERT_EXIT(cnt == 1); + ASSERT_EXIT(cnt,==,1U); - item = kdbus_get_item(info, KDBUS_ITEM_PIDS); - ASSERT_EXIT(item); + ASSERT_EXIT_NONZERO(item = kdbus_get_item(info, KDBUS_ITEM_PIDS)); /* Compare item->pids with cached pids */ - ASSERT_EXIT(item->pids.pid == cached_pids.pid && - item->pids.tid == cached_pids.tid); + ASSERT_EXIT(item->pids.pid,==,cached_pids.pid); + ASSERT_EXIT(item->pids.tid,==,cached_pids.tid); } cnt = kdbus_count_item(info, KDBUS_ITEM_CGROUP); - if (invalid_flags_set & KDBUS_ATTACH_CGROUP) { - ASSERT_EXIT(cnt == 1); - } else { - ASSERT_EXIT(cnt == 0); - } + if (invalid_flags & KDBUS_ATTACH_CGROUP) + ASSERT_EXIT(cnt,==,1U); + else + ASSERT_EXIT_ZERO(cnt); cnt = kdbus_count_item(info, KDBUS_ITEM_CAPS); - if (invalid_flags_set & KDBUS_ATTACH_CAPS) { - ASSERT_EXIT(cnt == 1); - } else { - ASSERT_EXIT(cnt == 0); - } + if (invalid_flags & KDBUS_ATTACH_CAPS) + ASSERT_EXIT(cnt,==,1U); + else + ASSERT_EXIT_ZERO(cnt); - kdbus_free(conn, offset); + ASSERT_ZERO(kdbus_free(conn, offset)); }), - ({ 0; })); - ASSERT_RETURN(ret == 0); + ({})); continue_test: /* A second name */ - ret = kdbus_name_acquire(conn, "com.example.b", NULL); - ASSERT_RETURN(ret >= 0); + ASSERT_ZERO(kdbus_name_acquire(conn, "com.example.b", NULL)); - ret = kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset)); info = (struct kdbus_info *)(conn->buf + offset); - ASSERT_RETURN(info->id == conn->id); + ASSERT_RETURN(info->id,==,conn->id); cnt = kdbus_count_item(info, KDBUS_ITEM_OWNED_NAME); - if (valid_flags_set & KDBUS_ATTACH_NAMES) { - ASSERT_RETURN(cnt == 2); - } else { - ASSERT_RETURN(cnt == 0); - } - - kdbus_free(conn, offset); + if (valid_flags & KDBUS_ATTACH_NAMES) + ASSERT_RETURN(cnt,==,2U); + else + ASSERT_RETURN(cnt,==,0U); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_free(conn, offset)); return 0; } -int kdbus_test_conn_info(struct kdbus_test_env *env) +wur int kdbus_test_conn_info(struct kdbus_test_env *env) { - int ret; int have_caps; struct { struct kdbus_cmd_info cmd_info; @@ -474,8 +404,7 @@ int kdbus_test_conn_info(struct kdbus_test_env *env) buf.cmd_info.attach_flags = 0; buf.cmd_info.id = env->conn->id; - ret = kdbus_conn_info(env->conn, env->conn->id, NULL, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(env->conn, env->conn->id, NULL, 0, NULL)); /* try to pass a name that is longer than the buffer's size */ buf.name.size = KDBUS_ITEM_HEADER_SIZE + 1; @@ -484,22 +413,19 @@ int kdbus_test_conn_info(struct kdbus_test_env *env) buf.cmd_info.id = 0; buf.cmd_info.size = sizeof(buf.cmd_info) + buf.name.size; - ret = kdbus_cmd_conn_info(env->conn->fd, (struct kdbus_cmd_info *) &buf); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_cmd_conn_info(env->conn->fd, (struct kdbus_cmd_info *) &buf)); /* Pass a non existent name */ - ret = kdbus_conn_info(env->conn, 0, "non.existent.name", 0, NULL); - ASSERT_RETURN(ret == -ESRCH); + ASSERT_RETURN(-ESRCH,==,kdbus_conn_info(env->conn, 0, "non.existent.name", 0, NULL)); if (!all_uids_gids_are_mapped()) return TEST_SKIP; /* Test for caps here, so we run the previous test */ have_caps = test_is_capable(CAP_SETUID, CAP_SETGID, -1); - ASSERT_RETURN(have_caps >= 0); + ASSERT_RETURN(have_caps,>=,0); - ret = kdbus_fuzz_conn_info(env, have_caps); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_fuzz_conn_info(env, have_caps)); /* Now if we have skipped some tests then let the user know */ if (!have_caps) @@ -508,12 +434,11 @@ int kdbus_test_conn_info(struct kdbus_test_env *env) return TEST_OK; } -int kdbus_test_conn_update(struct kdbus_test_env *env) +wur int kdbus_test_conn_update(struct kdbus_test_env *env) { struct kdbus_conn *conn; struct kdbus_msg *msg; int found = 0; - int ret; /* * kdbus_hello() sets all attach flags. Receive a message by this @@ -521,17 +446,14 @@ int kdbus_test_conn_update(struct kdbus_test_env *env) * present. */ conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn); - ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id, - 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id)); - ret = kdbus_msg_recv(conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(conn, &msg, NULL)); found = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP); - ASSERT_RETURN(found == 1); + ASSERT_RETURN(found,==,1); kdbus_msg_free(msg); @@ -541,27 +463,17 @@ int kdbus_test_conn_update(struct kdbus_test_env *env) */ found = 0; - ret = kdbus_conn_update_attach_flags(conn, - _KDBUS_ATTACH_ALL, - _KDBUS_ATTACH_ALL & - ~KDBUS_ATTACH_TIMESTAMP); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_attach_flags(conn, _KDBUS_ATTACH_ALL, _KDBUS_ATTACH_ALL & ~KDBUS_ATTACH_TIMESTAMP)); - ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id, - 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id)); - ret = kdbus_msg_recv(conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(conn, &msg, NULL)); found = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP); - ASSERT_RETURN(found == 0); + ASSERT_ZERO(found); /* Provide a bogus attach_flags value */ - ret = kdbus_conn_update_attach_flags(conn, - _KDBUS_ATTACH_ALL + 1, - _KDBUS_ATTACH_ALL); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_conn_update_attach_flags(conn, _KDBUS_ATTACH_ALL + 1, _KDBUS_ATTACH_ALL)); kdbus_msg_free(msg); @@ -570,15 +482,15 @@ int kdbus_test_conn_update(struct kdbus_test_env *env) return TEST_OK; } -int kdbus_test_writable_pool(struct kdbus_test_env *env) +wur int kdbus_test_writable_pool(struct kdbus_test_env *env) { struct kdbus_cmd_free cmd_free = {}; struct kdbus_cmd_hello hello; - int fd, ret; + int fd; void *map; fd = open(env->buspath, O_RDWR | O_CLOEXEC); - ASSERT_RETURN(fd >= 0); + ASSERT_RETURN(fd,>=,0); memset(&hello, 0, sizeof(hello)); hello.flags = KDBUS_HELLO_ACCEPT_FD; @@ -589,30 +501,27 @@ int kdbus_test_writable_pool(struct kdbus_test_env *env) hello.offset = (__u64)-1; /* success test */ - ret = kdbus_cmd_hello(fd, &hello); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_hello(fd, &hello)); /* The kernel should have returned some items */ - ASSERT_RETURN(hello.offset != (__u64)-1); + ASSERT_RETURN(hello.offset,!=,(__u64)-1); cmd_free.size = sizeof(cmd_free); cmd_free.offset = hello.offset; - ret = kdbus_cmd_free(fd, &cmd_free); - ASSERT_RETURN(ret >= 0); + ASSERT_ZERO(kdbus_cmd_free(fd, &cmd_free)); /* pools cannot be mapped writable */ map = mmap(NULL, POOL_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - ASSERT_RETURN(map == MAP_FAILED); + ASSERT_RETURN(map,==,MAP_FAILED); /* pools can always be mapped readable */ map = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); - ASSERT_RETURN(map != MAP_FAILED); + ASSERT_RETURN(map,!=,MAP_FAILED); /* make sure we cannot change protection masks to writable */ - ret = mprotect(map, POOL_SIZE, PROT_READ | PROT_WRITE); - ASSERT_RETURN(ret < 0); + ASSERT_RETURN(0,>,mprotect(map, POOL_SIZE, PROT_READ | PROT_WRITE)); munmap(map, POOL_SIZE); - close(fd); + CLOSE(fd); return TEST_OK; } diff --git a/tools/testing/selftests/kdbus/test-daemon.c b/tools/testing/selftests/kdbus/test-daemon.c index 8bc2386..066940e 100644 --- a/tools/testing/selftests/kdbus/test-daemon.c +++ b/tools/testing/selftests/kdbus/test-daemon.c @@ -15,7 +15,7 @@ #include "kdbus-util.h" #include "kdbus-enum.h" -int kdbus_test_daemon(struct kdbus_test_env *env) +wur int kdbus_test_daemon(struct kdbus_test_env *env) { struct pollfd fds[2]; int count; @@ -25,17 +25,16 @@ int kdbus_test_daemon(struct kdbus_test_env *env) if (!kdbus_util_verbose) return TEST_OK; - printf("Created connection %llu on bus '%s'\n", + print("Created connection %llu on bus '%s'\n", (unsigned long long) env->conn->id, env->buspath); - ret = kdbus_name_acquire(env->conn, "com.example.kdbus-test", NULL); - ASSERT_RETURN(ret == 0); - printf(" Aquired name: com.example.kdbus-test\n"); + ASSERT_ZERO(kdbus_name_acquire(env->conn, "com.example.kdbus-test", NULL)); + print(" Aquired name: com.example.kdbus-test\n"); fds[0].fd = env->conn->fd; fds[1].fd = STDIN_FILENO; - printf("Monitoring connections:\n"); + print("Monitoring connections:\n"); for (count = 0;; count++) { int i, nfds = sizeof(fds) / sizeof(fds[0]); @@ -49,17 +48,15 @@ int kdbus_test_daemon(struct kdbus_test_env *env) if (ret <= 0) break; - if (fds[0].revents & POLLIN) { - ret = kdbus_msg_recv(env->conn, NULL, NULL); - ASSERT_RETURN(ret == 0); - } + if (fds[0].revents & POLLIN) + ASSERT_ZERO(kdbus_msg_recv(env->conn, NULL, NULL)); /* stdin */ if (fds[1].revents & POLLIN) break; } - printf("Closing bus connection\n"); + print("Closing bus connection\n"); return TEST_OK; } diff --git a/tools/testing/selftests/kdbus/test-endpoint.c b/tools/testing/selftests/kdbus/test-endpoint.c index dcc6ab9..a3e143f 100644 --- a/tools/testing/selftests/kdbus/test-endpoint.c +++ b/tools/testing/selftests/kdbus/test-endpoint.c @@ -19,7 +19,7 @@ #define KDBUS_SYSNAME_MAX_LEN 63 -static int install_name_add_match(struct kdbus_conn *conn, const char *name) +static wur int install_name_add_match(struct kdbus_conn *conn, const char *name) { struct { struct kdbus_cmd_match cmd; @@ -48,7 +48,7 @@ static int install_name_add_match(struct kdbus_conn *conn, const char *name) return 0; } -static int create_endpoint(const char *buspath, uid_t uid, const char *name, +static wur int create_endpoint(const char *buspath, uid_t uid, const char *name, uint64_t flags) { struct { @@ -92,34 +92,33 @@ static int create_endpoint(const char *buspath, uid_t uid, const char *name, return fd; } -static int unpriv_test_custom_ep(const char *buspath) +static wur int unpriv_test_custom_ep(const char *buspath) { int ret, ep_fd1, ep_fd2; char *ep1, *ep2, *tmp1, *tmp2; - tmp1 = strdup(buspath); - tmp2 = strdup(buspath); - ASSERT_RETURN(tmp1 && tmp2); + ASSERT_NONZERO(tmp1 = strdup(buspath)); + ASSERT_NONZERO(tmp2 = strdup(buspath)); ret = asprintf(&ep1, "%s/%u-%s", dirname(tmp1), getuid(), "apps1"); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>,0); ret = asprintf(&ep2, "%s/%u-%s", dirname(tmp2), getuid(), "apps2"); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>,0); free(tmp1); free(tmp2); /* endpoint only accessible to current uid */ ep_fd1 = create_endpoint(buspath, getuid(), "apps1", 0); - ASSERT_RETURN(ep_fd1 >= 0); + ASSERT_RETURN(ep_fd1,>=,0); /* endpoint world accessible */ ep_fd2 = create_endpoint(buspath, getuid(), "apps2", KDBUS_MAKE_ACCESS_WORLD); - ASSERT_RETURN(ep_fd2 >= 0); + ASSERT_RETURN(ep_fd2,>=,0); - ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({ + RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({ int ep_fd; struct kdbus_conn *ep_conn; @@ -129,35 +128,34 @@ static int unpriv_test_custom_ep(const char *buspath) */ ep_fd = create_endpoint(buspath, getuid(), "unpriv_costum_ep", 0); - ASSERT_EXIT(ep_fd == -EPERM); + ASSERT_EXIT(ep_fd,==,-EPERM); /* * Endpoint "apps1" only accessible to same users, * that own the endpoint. Access denied by VFS */ ep_conn = kdbus_hello(ep1, 0, NULL, 0); - ASSERT_EXIT(!ep_conn && errno == EACCES); + ASSERT_EXIT(errno,==,EACCES); + ASSERT_EXIT_ZERO(ep_conn); /* Endpoint "apps2" world accessible */ - ep_conn = kdbus_hello(ep2, 0, NULL, 0); - ASSERT_EXIT(ep_conn); + ASSERT_EXIT_NONZERO(ep_conn = kdbus_hello(ep2, 0, NULL, 0)); kdbus_conn_free(ep_conn); - _exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); }), - ({ 0; })); - ASSERT_RETURN(ret == 0); + ({})); - close(ep_fd1); - close(ep_fd2); + CLOSE(ep_fd1); + CLOSE(ep_fd2); free(ep1); free(ep2); return 0; } -static int update_endpoint(int fd, const char *name) +static wur int update_endpoint(int fd, const char *name) { int len = strlen(name) + 1; struct { @@ -200,7 +198,7 @@ static int update_endpoint(int fd, const char *name) return 0; } -int kdbus_test_custom_endpoint(struct kdbus_test_env *env) +wur int kdbus_test_custom_endpoint(struct kdbus_test_env *env) { char *ep, *tmp; int ret, ep_fd; @@ -214,46 +212,38 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env) memset(fake_ep, 'X', sizeof(fake_ep) - 1); /* Try to create a custom endpoint with a long name */ - ret = create_endpoint(env->buspath, getuid(), fake_ep, 0); - ASSERT_RETURN(ret == -ENAMETOOLONG); + ASSERT_RETURN(-ENAMETOOLONG,==,create_endpoint(env->buspath, getuid(), fake_ep, 0)); /* Try to create a custom endpoint with a different uid */ - ret = create_endpoint(env->buspath, getuid() + 1, "foobar", 0); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,create_endpoint(env->buspath, getuid() + 1, "foobar", 0)); /* create a custom endpoint, and open a connection on it */ - ep_fd = create_endpoint(env->buspath, getuid(), "foo", 0); - ASSERT_RETURN(ep_fd >= 0); + ASSERT_RETURN(0,<=,ep_fd = create_endpoint(env->buspath, getuid(), "foo", 0)); - tmp = strdup(env->buspath); - ASSERT_RETURN(tmp); - - ret = asprintf(&ep, "%s/%u-%s", dirname(tmp), getuid(), epname); + ASSERT_NONZERO(tmp = strdup(env->buspath)); + ASSERT_RETURN(0,<=,asprintf(&ep, "%s/%u-%s", dirname(tmp), getuid(), epname)); free(tmp); - ASSERT_RETURN(ret >= 0); /* Register a connection that listen to broadcasts */ - reader = kdbus_hello(ep, 0, NULL, 0); - ASSERT_RETURN(reader); + ASSERT_NONZERO(reader = kdbus_hello(ep, 0, NULL, 0)); /* Register to kernel signals */ - ret = kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD, - KDBUS_MATCH_ID_ANY); - ASSERT_RETURN(ret == 0); - - ret = kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE, - KDBUS_MATCH_ID_ANY); - ASSERT_RETURN(ret == 0); - - ret = install_name_add_match(reader, name); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD, KDBUS_MATCH_ID_ANY)); + ASSERT_ZERO(kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE, KDBUS_MATCH_ID_ANY)); + ASSERT_ZERO(install_name_add_match(reader, name)); /* Monitor connections are not supported on custom endpoints */ ep_conn = kdbus_hello(ep, KDBUS_HELLO_MONITOR, NULL, 0); - ASSERT_RETURN(!ep_conn && errno == EOPNOTSUPP); + ASSERT_RETURN(errno,==,EOPNOTSUPP); + ASSERT_ZERO(ep_conn); - ep_conn = kdbus_hello(ep, 0, NULL, 0); - ASSERT_RETURN(ep_conn); + ASSERT_NONZERO(ep_conn = kdbus_hello(ep, 0, NULL, 0)); + + /* Check that the reader got the IdAdd notification */ + ASSERT_ZERO(kdbus_msg_recv(reader, &msg, NULL)); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_ID_ADD); + ASSERT_RETURN(msg->items[0].id_change.id,==,ep_conn->id); + kdbus_msg_free(msg); /* * Add a name add match on the endpoint connection, acquire name from @@ -262,80 +252,62 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env) * endpoint connection may not be able to call conn_info, neither on * the name nor on the ID. */ - ret = install_name_add_match(ep_conn, name); - ASSERT_RETURN(ret == 0); - - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(install_name_add_match(ep_conn, name)); - ret = kdbus_msg_recv(ep_conn, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, NULL)); - ret = kdbus_conn_info(ep_conn, 0, name, 0, NULL); - ASSERT_RETURN(ret == -ESRCH); + ASSERT_RETURN(ONTIZEN(0,-EAGAIN),==,kdbus_msg_recv(ep_conn, NULL, NULL)); + ASSERT_RETURN(ONTIZEN(0,-ESRCH),==,kdbus_conn_info(ep_conn, 0, name, 0, NULL)); + ASSERT_RETURN(-ESRCH,==,kdbus_conn_info(ep_conn, 0, "random.crappy.name", 0, NULL)); + ASSERT_RETURN(ONTIZEN(0,-ENXIO),==,kdbus_conn_info(ep_conn, env->conn->id, NULL, 0, NULL)); + ASSERT_RETURN(-ENXIO,==,kdbus_conn_info(ep_conn, 0x0fffffffffffffffULL, NULL, 0, NULL)); - ret = kdbus_conn_info(ep_conn, 0, "random.crappy.name", 0, NULL); - ASSERT_RETURN(ret == -ESRCH); - - ret = kdbus_conn_info(ep_conn, env->conn->id, NULL, 0, NULL); - ASSERT_RETURN(ret == -ENXIO); - - ret = kdbus_conn_info(ep_conn, 0x0fffffffffffffffULL, NULL, 0, NULL); - ASSERT_RETURN(ret == -ENXIO); - - /* Check that the reader did not receive anything */ - ret = kdbus_msg_recv(reader, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + /* Check that the reader did not receive the name notification */ + ASSERT_RETURN(ONTIZEN(0,-EAGAIN),==,kdbus_msg_recv(reader, NULL, NULL)); /* * Release the name again, update the custom endpoint policy, * and try again. This time, the connection on the custom endpoint * should have gotten it. */ - ret = kdbus_name_release(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_release(env->conn, name)); - ret = update_endpoint(ep_fd, name); - ASSERT_RETURN(ret == 0); + /* Check that the reader did not receive the name notification */ + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(reader, NULL, NULL)); - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(update_endpoint(ep_fd, name)); - ret = kdbus_msg_recv(ep_conn, &msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_ADD); - ASSERT_RETURN(msg->items[0].name_change.old_id.id == 0); - ASSERT_RETURN(msg->items[0].name_change.new_id.id == env->conn->id); - ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0); + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, NULL)); + + ASSERT_ZERO(kdbus_msg_recv(ep_conn, &msg, NULL)); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_NAME_ADD); + ASSERT_ZERO(msg->items[0].name_change.old_id.id); + ASSERT_RETURN(msg->items[0].name_change.new_id.id,==,env->conn->id); + ASSERT_ZERO(strcmp(msg->items[0].name_change.name, name)); kdbus_msg_free(msg); - ret = kdbus_msg_recv(reader, &msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0); + ASSERT_ZERO(kdbus_msg_recv(reader, &msg, NULL)); + ASSERT_ZERO(strcmp(msg->items[0].name_change.name, name)); kdbus_msg_free(msg); - ret = kdbus_conn_info(ep_conn, 0, name, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(ep_conn, 0, name, 0, NULL)); - ret = kdbus_conn_info(ep_conn, env->conn->id, NULL, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_info(ep_conn, env->conn->id, NULL, 0, NULL)); /* If we have privileges test custom endpoints */ ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); /* * All uids/gids are mapped and we have the necessary caps */ - if (ret && all_uids_gids_are_mapped()) { - ret = unpriv_test_custom_ep(env->buspath); - ASSERT_RETURN(ret == 0); - } + if (ret && all_uids_gids_are_mapped()) + ASSERT_ZERO(unpriv_test_custom_ep(env->buspath)); kdbus_conn_free(reader); kdbus_conn_free(ep_conn); - close(ep_fd); + CLOSE(ep_fd); return TEST_OK; } diff --git a/tools/testing/selftests/kdbus/test-fd.c b/tools/testing/selftests/kdbus/test-fd.c index bfd8980..6f315a9 100644 --- a/tools/testing/selftests/kdbus/test-fd.c +++ b/tools/testing/selftests/kdbus/test-fd.c @@ -13,29 +13,30 @@ #include #include #include +#include #include "kdbus-api.h" #include "kdbus-test.h" #include "kdbus-util.h" #include "kdbus-enum.h" -#define KDBUS_MSG_MAX_ITEMS 128 -#define KDBUS_USER_MAX_CONN 256 +#define KDBUS_MSG_MAX_ITEMS 128U +#define KDBUS_USER_MAX_CONN 256U /* maximum number of inflight fds in a target queue per user */ -#define KDBUS_CONN_MAX_FDS_PER_USER 16 +#define KDBUS_CONN_MAX_FDS_PER_USER 16U /* maximum number of memfd items per message */ -#define KDBUS_MSG_MAX_MEMFD_ITEMS 16 +#define KDBUS_MSG_MAX_MEMFD_ITEMS 16U -static int make_msg_payload_dbus(uint64_t src_id, uint64_t dst_id, +static wur int make_msg_payload_dbus(uint64_t src_id, uint64_t dst_id, uint64_t msg_size, struct kdbus_msg **msg_dbus) { struct kdbus_msg *msg; - msg = malloc(msg_size); - ASSERT_RETURN_VAL(msg, -ENOMEM); + msg = alloc(msg_size); + ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM); memset(msg, 0, msg_size); msg->size = msg_size; @@ -74,24 +75,24 @@ static void make_item_fds(struct kdbus_item *item, item->fds[i] = fd_array[i]; } -static int memfd_write(const char *name, void *buf, size_t bufsize) +static wur int memfd_write(const char *name, void *buf, size_t bufsize) { ssize_t ret; int memfd; memfd = sys_memfd_create(name, 0); - ASSERT_RETURN_VAL(memfd >= 0, memfd); + ASSERT_RETURN_VAL(memfd,>=,0, memfd); ret = write(memfd, buf, bufsize); - ASSERT_RETURN_VAL(ret == (ssize_t)bufsize, -EAGAIN); + ASSERT_RETURN_VAL(ret,==,(ssize_t)bufsize, -EAGAIN); ret = sys_memfd_seal_set(memfd); - ASSERT_RETURN_VAL(ret == 0, -errno); + ASSERT_RETURN_VAL(ret,==,0, -errno); return memfd; } -static int send_memfds(struct kdbus_conn *conn, uint64_t dst_id, +static wur int send_memfds(struct kdbus_conn *conn, uint64_t dst_id, int *memfds_array, size_t memfd_count) { struct kdbus_cmd_send cmd = {}; @@ -107,7 +108,7 @@ static int send_memfds(struct kdbus_conn *conn, uint64_t dst_id, size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); item = msg->items; @@ -134,7 +135,7 @@ static int send_memfds(struct kdbus_conn *conn, uint64_t dst_id, return 0; } -static int send_fds(struct kdbus_conn *conn, uint64_t dst_id, +static wur int send_fds(struct kdbus_conn *conn, uint64_t dst_id, int *fd_array, size_t fd_count) { struct kdbus_cmd_send cmd = {}; @@ -150,7 +151,7 @@ static int send_fds(struct kdbus_conn *conn, uint64_t dst_id, size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); item = msg->items; @@ -177,7 +178,7 @@ static int send_fds(struct kdbus_conn *conn, uint64_t dst_id, return ret; } -static int send_fds_memfds(struct kdbus_conn *conn, uint64_t dst_id, +static wur int send_fds_memfds(struct kdbus_conn *conn, uint64_t dst_id, int *fds_array, size_t fd_count, int *memfds_array, size_t memfd_count) { @@ -192,7 +193,7 @@ static int send_fds_memfds(struct kdbus_conn *conn, uint64_t dst_id, size += KDBUS_ITEM_SIZE(sizeof(int) * fd_count); ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); item = msg->items; @@ -213,33 +214,7 @@ static int send_fds_memfds(struct kdbus_conn *conn, uint64_t dst_id, return ret; } -/* Return the number of received fds */ -static unsigned int kdbus_item_get_nfds(struct kdbus_msg *msg) -{ - unsigned int fds = 0; - const struct kdbus_item *item; - - KDBUS_ITEM_FOREACH(item, msg, items) { - switch (item->type) { - case KDBUS_ITEM_FDS: { - fds += (item->size - KDBUS_ITEM_HEADER_SIZE) / - sizeof(int); - break; - } - - case KDBUS_ITEM_PAYLOAD_MEMFD: - fds++; - break; - - default: - break; - } - } - - return fds; -} - -static struct kdbus_msg * +static wur struct kdbus_msg * get_kdbus_msg_with_fd(struct kdbus_conn *conn_src, uint64_t dst_id, uint64_t cookie, int fd) { @@ -253,7 +228,7 @@ get_kdbus_msg_with_fd(struct kdbus_conn *conn_src, size += KDBUS_ITEM_SIZE(sizeof(int)); ret = make_msg_payload_dbus(conn_src->id, dst_id, size, &msg); - ASSERT_RETURN_VAL(ret == 0, NULL); + ASSERT_RETURN_VAL(ret,==,0, NULL); msg->cookie = cookie; @@ -266,7 +241,7 @@ get_kdbus_msg_with_fd(struct kdbus_conn *conn_src, return msg; } -static int kdbus_test_no_fds(struct kdbus_test_env *env, +static wur int kdbus_test_no_fds(struct kdbus_test_env *env, int *fds, int *memfd) { pid_t pid; @@ -279,84 +254,75 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, struct kdbus_cmd_send cmd = {}; struct kdbus_cmd_free cmd_free = {}; - conn_src = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_src); + ASSERT_NONZERO(conn_src = kdbus_hello(env->buspath, 0, NULL, 0)); connfd1 = open(env->buspath, O_RDWR|O_CLOEXEC); - ASSERT_RETURN(connfd1 >= 0); + ASSERT_RETURN(connfd1,>=,0); connfd2 = open(env->buspath, O_RDWR|O_CLOEXEC); - ASSERT_RETURN(connfd2 >= 0); + ASSERT_RETURN(connfd2,>=,0); /* * Create connections without KDBUS_HELLO_ACCEPT_FD * to test if send fd operations are blocked */ - conn_dst = malloc(sizeof(*conn_dst)); - ASSERT_RETURN(conn_dst); - - conn_dummy = malloc(sizeof(*conn_dummy)); - ASSERT_RETURN(conn_dummy); + ASSERT_NONZERO(conn_dst = alloc(sizeof(*conn_dst))); + ASSERT_NONZERO(conn_dummy = alloc(sizeof(*conn_dummy))); memset(&hello, 0, sizeof(hello)); hello.size = sizeof(struct kdbus_cmd_hello); hello.pool_size = POOL_SIZE; hello.attach_flags_send = _KDBUS_ATTACH_ALL; - ret = kdbus_cmd_hello(connfd1, &hello); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_hello(connfd1, &hello)); cmd_free.size = sizeof(cmd_free); cmd_free.offset = hello.offset; - ret = kdbus_cmd_free(connfd1, &cmd_free); - ASSERT_RETURN(ret >= 0); + ASSERT_ZERO(kdbus_cmd_free(connfd1, &cmd_free)); conn_dst->fd = connfd1; conn_dst->id = hello.id; + conn_dst->attach_flags_recv = 0; memset(&hello, 0, sizeof(hello)); hello.size = sizeof(struct kdbus_cmd_hello); hello.pool_size = POOL_SIZE; hello.attach_flags_send = _KDBUS_ATTACH_ALL; - ret = kdbus_cmd_hello(connfd2, &hello); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_hello(connfd2, &hello)); cmd_free.size = sizeof(cmd_free); cmd_free.offset = hello.offset; - ret = kdbus_cmd_free(connfd2, &cmd_free); - ASSERT_RETURN(ret >= 0); + ASSERT_ZERO(kdbus_cmd_free(connfd2, &cmd_free)); conn_dummy->fd = connfd2; conn_dummy->id = hello.id; + conn_dummy->attach_flags_recv = 0; conn_dst->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, connfd1, 0); - ASSERT_RETURN(conn_dst->buf != MAP_FAILED); + ASSERT_RETURN(conn_dst->buf,!=,MAP_FAILED); conn_dummy->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, connfd2, 0); - ASSERT_RETURN(conn_dummy->buf != MAP_FAILED); + ASSERT_RETURN(conn_dummy->buf,!=,MAP_FAILED); /* * Send fds to connection that do not accept fd passing */ - ret = send_fds(conn_src, conn_dst->id, fds, 1); - ASSERT_RETURN(ret == -ECOMM); + ASSERT_RETURN(-ECOMM,==,send_fds(conn_src, conn_dst->id, fds, 1)); /* * memfd are kdbus payload */ - ret = send_memfds(conn_src, conn_dst->id, memfd, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_memfds(conn_src, conn_dst->id, memfd, 1)); - ret = kdbus_msg_recv_poll(conn_dst, 100, NULL, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(conn_dst, 100, NULL, NULL)); cookie = time(NULL); pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, pid); + ASSERT_RETURN_VAL(pid,>=,0, pid); if (pid == 0) { struct timespec now; @@ -365,13 +331,9 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, * A sync send/reply to a connection that do not * accept fds should fail if it contains an fd */ - msg_sync_reply = get_kdbus_msg_with_fd(conn_dst, - conn_dummy->id, - cookie, fds[0]); - ASSERT_EXIT(msg_sync_reply); + ASSERT_EXIT_NONZERO(msg_sync_reply = get_kdbus_msg_with_fd(conn_dst, conn_dummy->id, cookie, fds[0])); - ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(clock_gettime(CLOCK_MONOTONIC_COARSE, &now)); msg_sync_reply->timeout_ns = now.tv_sec * 1000000000ULL + now.tv_nsec + 100000000ULL; @@ -382,8 +344,7 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, cmd.msg_address = (uintptr_t)msg_sync_reply; cmd.flags = KDBUS_SEND_SYNC_REPLY; - ret = kdbus_cmd_send(conn_dst->fd, &cmd); - ASSERT_EXIT(ret == -ECOMM); + ASSERT_EXIT(-ECOMM,==,kdbus_cmd_send(conn_dst->fd, &cmd)); /* * Now send a normal message, but the sync reply @@ -393,28 +354,23 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, * The original sender will fail with -ETIMEDOUT */ cookie++; - ret = kdbus_msg_send_sync(conn_dst, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - 5000000000ULL, 0, conn_src->id, -1); - ASSERT_EXIT(ret == -EREMOTEIO); + ASSERT_EXIT(-EREMOTEIO,==,kdbus_msg_send_sync(conn_dst, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, 5000000000ULL, 0, conn_src->id, -1)); cookie++; - ret = kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL); - ASSERT_EXIT(ret == 0); - ASSERT_EXIT(msg->cookie == cookie); + ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL)); + ASSERT_EXIT(msg->cookie,==,cookie); free(msg_sync_reply); kdbus_msg_free(msg); - _exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } - ret = kdbus_msg_recv_poll(conn_dummy, 100, NULL, NULL); - ASSERT_RETURN(ret == -ETIMEDOUT); + ASSERT_RETURN(-ETIMEDOUT,==,kdbus_msg_recv_poll(conn_dummy, 100, NULL, NULL)); cookie++; - ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL); - ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv_poll(conn_src, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); @@ -425,7 +381,7 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, msg_sync_reply = get_kdbus_msg_with_fd(conn_src, conn_dst->id, cookie, conn_dst->fd); - ASSERT_RETURN(msg_sync_reply); + ASSERT_NONZERO(msg_sync_reply); msg_sync_reply->cookie_reply = cookie; @@ -433,8 +389,7 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, cmd.size = sizeof(cmd); cmd.msg_address = (uintptr_t)msg_sync_reply; - ret = kdbus_cmd_send(conn_src->fd, &cmd); - ASSERT_RETURN(ret == -EOPNOTSUPP); + ASSERT_RETURN(-EOPNOTSUPP,==,kdbus_cmd_send(conn_src->fd, &cmd)); free(msg_sync_reply); @@ -447,7 +402,7 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, msg_sync_reply = get_kdbus_msg_with_fd(conn_src, conn_dst->id, cookie, fds[0]); - ASSERT_RETURN(msg_sync_reply); + ASSERT_NONZERO(msg_sync_reply); msg_sync_reply->cookie_reply = cookie; @@ -455,8 +410,7 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, cmd.size = sizeof(cmd); cmd.msg_address = (uintptr_t)msg_sync_reply; - ret = kdbus_cmd_send(conn_src->fd, &cmd); - ASSERT_RETURN(ret == -ECOMM); + ASSERT_RETURN(-ECOMM,==,kdbus_cmd_send(conn_src->fd, &cmd)); free(msg_sync_reply); @@ -465,12 +419,10 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, * is clear */ cookie++; - ret = kdbus_msg_send(conn_src, NULL, cookie, 0, 0, 0, - conn_dst->id, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn_src, NULL, cookie, 0, 0, 0, conn_dst->id)); ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); kdbus_conn_free(conn_dummy); kdbus_conn_free(conn_dst); @@ -479,179 +431,217 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env, return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR; } -static int kdbus_send_multiple_fds(struct kdbus_conn *conn_src, +#define VALUE_CHECKED_SEED 0 +uint64_t value_checked_out = VALUE_CHECKED_SEED; +uint64_t value_checked_in = VALUE_CHECKED_SEED; + +#define MAKE_FDS_(ARRAY_NAME,MAKE_ELEM) do {\ + unsigned _MAKE_FDS_i_ = 0;\ + do {\ + ASSERT_RETURN(-1,==,ARRAY_NAME[_MAKE_FDS_i_]);\ + ARRAY_NAME[_MAKE_FDS_i_] = MAKE_ELEM(++value_checked_out);\ + ASSERT_RETURN(0,<=,ARRAY_NAME[_MAKE_FDS_i_]);\ + } while (++_MAKE_FDS_i_ < ELEMENTSOF(ARRAY_NAME));\ +} while (0) + +#define REMAKE_FDS_(ARRAY_NAME,MAKE_ELEM) do {\ + CLOSE_FDS(ARRAY_NAME);\ + MAKE_FDS_(ARRAY_NAME,MAKE_ELEM);\ +} while (0) + +static wur int make_value_checked_fd(uint64_t value) { + int fd = eventfd(0, EFD_CLOEXEC); + if (fd < 0) { + int ret = -errno; + return ret<0 ? ret : -817; + } + if (eventfd_write(fd, value)) { + int ret = -errno; + return ret<0 ? ret : -818; + } + return fd; +} +static wur int make_value_checked_memfd(uint64_t value) { + return memfd_write("memfd-name", &value, sizeof(value)); +} + +#define D_FDS(ARRAY_NAME,COUNT) int ARRAY_NAME[COUNT] = { [0 ... COUNT-1] = -1 } + +#define CLOSE_FDS(ARRAY_NAME) do {\ + unsigned _CLOSE_FDS_i_ = 0;\ + do {\ + ASSERT_RETURN(0,<=,ARRAY_NAME[_CLOSE_FDS_i_]);\ + CLOSE(ARRAY_NAME[_CLOSE_FDS_i_]);\ + ARRAY_NAME[_CLOSE_FDS_i_] = -1;\ + } while (++_CLOSE_FDS_i_ < ELEMENTSOF(ARRAY_NAME));\ +} while (0) + +#define MAKE_FDS(ARRAY_NAME) MAKE_FDS_(ARRAY_NAME, make_value_checked_fd) +#define MAKE_MEMFDS(ARRAY_NAME) MAKE_FDS_(ARRAY_NAME, make_value_checked_memfd) +#define REMAKE_FDS(ARRAY_NAME) REMAKE_FDS_(ARRAY_NAME, make_value_checked_fd) +#define REMAKE_MEMFDS(ARRAY_NAME) REMAKE_FDS_(ARRAY_NAME, make_value_checked_memfd) + +static wur int check_fds(int togo, int total_count, struct kdbus_msg const *msg) { + struct kdbus_item const *item; + int surplus_count; + ASSERT_RETURN(0,<,togo); + ASSERT_RETURN(togo,<=,total_count); + surplus_count = total_count - togo; + KDBUS_ITEM_FOREACH(item, msg, items) + if (KDBUS_ITEM_FDS == item->type) { + unsigned n = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof(int); + unsigned i = 0; + ASSERT_NONZERO(togo); + for (; i < n; ++i) { + int fd = item->fds[i]; + if (-1 != fd) { + eventfd_t value = VALUE_CHECKED_SEED; + ASSERT_ZERO(eventfd_read(fd, &value)); + ASSERT_RETURN(value,==,++value_checked_in); + --togo; + } + } + ASSERT_ZERO(togo); + } + ASSERT_ZERO(togo); + value_checked_in += surplus_count; + return 0; +} + +static wur int check_memfds(int togo, int total_count, struct kdbus_msg const *msg) { + struct kdbus_item const *item; + int surplus_count; + ASSERT_RETURN(0,<,togo); + ASSERT_RETURN(togo,<=,total_count); + surplus_count = total_count - togo; + KDBUS_ITEM_FOREACH(item, msg, items) + if (KDBUS_ITEM_PAYLOAD_MEMFD == item->type) { + int fd; + ASSERT_NONZERO(togo); + fd = item->memfd.fd; + if (-1 != fd) { + typeof(value_checked_in) *buf; + off_t size; + --togo; + ASSERT_ZERO(sys_memfd_get_size(fd, &size)); + ASSERT_RETURN(size,==,(typeof(size))sizeof(value_checked_in)); + ASSERT_RETURN((uint64_t)size,==,item->memfd.size); + ASSERT_RETURN(MAP_FAILED, !=, (buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0))); + ASSERT_RETURN(*buf,==,++value_checked_in); + ASSERT_ZERO(munmap(buf, size)); + } + } + ASSERT_ZERO(togo); + value_checked_in += surplus_count; + return 0; +} + +#define CHECK_FDS(ARRAY,COUNT,MSG) ASSERT_ZERO(check_fds((COUNT), ELEMENTSOF((ARRAY)), (MSG))) +#define CHECK_MEMFDS(ARRAY,COUNT,MSG) ASSERT_ZERO(check_memfds((COUNT), ELEMENTSOF((ARRAY)), (MSG))) + +static wur int kdbus_send_multiple_fds(struct kdbus_conn *conn_src, struct kdbus_conn *conn_dst) { - int ret, i; - unsigned int nfds; - int fds[KDBUS_CONN_MAX_FDS_PER_USER + 1]; - int memfds[KDBUS_MSG_MAX_ITEMS + 1]; + D_FDS(fds, KDBUS_CONN_MAX_FDS_PER_USER + 1); + D_FDS(memfds, KDBUS_MSG_MAX_ITEMS + 1); struct kdbus_msg *msg; - uint64_t dummy_value; - dummy_value = time(NULL); - - for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++) { - fds[i] = open("/dev/null", O_RDWR|O_CLOEXEC); - ASSERT_RETURN_VAL(fds[i] >= 0, -errno); - } + MAKE_FDS(fds); /* Send KDBUS_CONN_MAX_FDS_PER_USER with one more fd */ - ret = send_fds(conn_src, conn_dst->id, fds, - KDBUS_CONN_MAX_FDS_PER_USER + 1); - ASSERT_RETURN(ret == -EMFILE); + ASSERT_RETURN(-EMFILE,==,send_fds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER + 1)); /* Retry with the correct KDBUS_CONN_MAX_FDS_PER_USER */ - ret = send_fds(conn_src, conn_dst->id, fds, - KDBUS_CONN_MAX_FDS_PER_USER); - ASSERT_RETURN(ret == 0); - - ret = kdbus_msg_recv(conn_dst, &msg, NULL); - ASSERT_RETURN(ret == 0); - - /* Check we got the right number of fds */ - nfds = kdbus_item_get_nfds(msg); - ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER); - + ASSERT_ZERO(send_fds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER)); + ASSERT_ZERO(kdbus_msg_recv(conn_dst, &msg, NULL)); + CHECK_FDS(fds, KDBUS_CONN_MAX_FDS_PER_USER, msg); kdbus_msg_free(msg); - for (i = 0; i < KDBUS_MSG_MAX_ITEMS + 1; i++, dummy_value++) { - memfds[i] = memfd_write("memfd-name", - &dummy_value, - sizeof(dummy_value)); - ASSERT_RETURN_VAL(memfds[i] >= 0, memfds[i]); - } + MAKE_MEMFDS(memfds); /* Send KDBUS_MSG_MAX_ITEMS with one more memfd */ - ret = send_memfds(conn_src, conn_dst->id, - memfds, KDBUS_MSG_MAX_ITEMS + 1); - ASSERT_RETURN(ret == -E2BIG); - - ret = send_memfds(conn_src, conn_dst->id, - memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1); - ASSERT_RETURN(ret == -E2BIG); + ASSERT_RETURN(-E2BIG,==,send_memfds(conn_src, conn_dst->id, memfds, KDBUS_MSG_MAX_ITEMS + 1)); + ASSERT_RETURN(-E2BIG,==,send_memfds(conn_src, conn_dst->id, memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1)); /* Retry with the correct KDBUS_MSG_MAX_ITEMS */ - ret = send_memfds(conn_src, conn_dst->id, - memfds, KDBUS_MSG_MAX_MEMFD_ITEMS); - ASSERT_RETURN(ret == 0); - - ret = kdbus_msg_recv(conn_dst, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_memfds(conn_src, conn_dst->id, memfds, KDBUS_MSG_MAX_MEMFD_ITEMS)); + ASSERT_ZERO(kdbus_msg_recv(conn_dst, &msg, NULL)); /* Check we got the right number of fds */ - nfds = kdbus_item_get_nfds(msg); - ASSERT_RETURN(nfds == KDBUS_MSG_MAX_MEMFD_ITEMS); - + CHECK_MEMFDS(memfds, KDBUS_MSG_MAX_MEMFD_ITEMS, msg); kdbus_msg_free(msg); + /* reinitialize descriptors and cookies to check no stale data gets passed */ + REMAKE_FDS(fds); + REMAKE_MEMFDS(memfds); /* * Combine multiple KDBUS_CONN_MAX_FDS_PER_USER+1 fds and * 10 memfds */ - ret = send_fds_memfds(conn_src, conn_dst->id, - fds, KDBUS_CONN_MAX_FDS_PER_USER + 1, - memfds, 10); - ASSERT_RETURN(ret == -EMFILE); - - ret = kdbus_msg_recv(conn_dst, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EMFILE,==,send_fds_memfds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER + 1, memfds, 10)); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn_dst, NULL, NULL)); /* * Combine multiple KDBUS_CONN_MAX_FDS_PER_USER fds and * (128 - 1) + 1 memfds, all fds take one item, while each * memfd takes one item */ - ret = send_fds_memfds(conn_src, conn_dst->id, - fds, KDBUS_CONN_MAX_FDS_PER_USER, - memfds, (KDBUS_MSG_MAX_ITEMS - 1) + 1); - ASSERT_RETURN(ret == -E2BIG); - - ret = send_fds_memfds(conn_src, conn_dst->id, - fds, KDBUS_CONN_MAX_FDS_PER_USER, - memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1); - ASSERT_RETURN(ret == -E2BIG); - - ret = kdbus_msg_recv(conn_dst, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-E2BIG,==,send_fds_memfds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER, memfds, (KDBUS_MSG_MAX_ITEMS - 1) + 1)); + ASSERT_RETURN(-E2BIG,==,send_fds_memfds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER, memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1)); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn_dst, NULL, NULL)); /* * Send KDBUS_CONN_MAX_FDS_PER_USER fds + * KDBUS_MSG_MAX_MEMFD_ITEMS memfds */ - ret = send_fds_memfds(conn_src, conn_dst->id, - fds, KDBUS_CONN_MAX_FDS_PER_USER, - memfds, KDBUS_MSG_MAX_MEMFD_ITEMS); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_fds_memfds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER, memfds, KDBUS_MSG_MAX_MEMFD_ITEMS)); - ret = kdbus_msg_recv(conn_dst, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(conn_dst, &msg, NULL)); /* Check we got the right number of fds */ - nfds = kdbus_item_get_nfds(msg); - ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER + - KDBUS_MSG_MAX_MEMFD_ITEMS); - + CHECK_FDS(fds, KDBUS_CONN_MAX_FDS_PER_USER, msg); + CHECK_MEMFDS(memfds, KDBUS_MSG_MAX_MEMFD_ITEMS, msg); kdbus_msg_free(msg); + /* reinitialize descriptors and cookies to check no stale data gets passed */ + REMAKE_FDS(fds); + REMAKE_MEMFDS(memfds); /* * Re-send fds + memfds, close them, but do not receive them * and try to queue more */ - ret = send_fds_memfds(conn_src, conn_dst->id, - fds, KDBUS_CONN_MAX_FDS_PER_USER, - memfds, KDBUS_MSG_MAX_MEMFD_ITEMS); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_fds_memfds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER, memfds, KDBUS_MSG_MAX_MEMFD_ITEMS)); /* close old references and get a new ones */ - for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++) { - close(fds[i]); - fds[i] = open("/dev/null", O_RDWR|O_CLOEXEC); - ASSERT_RETURN_VAL(fds[i] >= 0, -errno); - } + REMAKE_FDS(fds); /* should fail since we have already fds in the queue */ - ret = send_fds(conn_src, conn_dst->id, fds, - KDBUS_CONN_MAX_FDS_PER_USER); - ASSERT_RETURN(ret == -EMFILE); + ASSERT_RETURN(-EMFILE,==,send_fds(conn_src, conn_dst->id, fds, KDBUS_CONN_MAX_FDS_PER_USER)); /* This should succeed */ - ret = send_memfds(conn_src, conn_dst->id, - memfds, KDBUS_MSG_MAX_MEMFD_ITEMS); - ASSERT_RETURN(ret == 0); - - ret = kdbus_msg_recv(conn_dst, &msg, NULL); - ASSERT_RETURN(ret == 0); - - nfds = kdbus_item_get_nfds(msg); - ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER + - KDBUS_MSG_MAX_MEMFD_ITEMS); - + ASSERT_ZERO(send_memfds(conn_src, conn_dst->id, memfds, KDBUS_MSG_MAX_MEMFD_ITEMS)); + ASSERT_ZERO(kdbus_msg_recv(conn_dst, &msg, NULL)); + CHECK_FDS(fds, KDBUS_CONN_MAX_FDS_PER_USER, msg); + CHECK_MEMFDS(memfds, KDBUS_MSG_MAX_MEMFD_ITEMS, msg); kdbus_msg_free(msg); - ret = kdbus_msg_recv(conn_dst, &msg, NULL); - ASSERT_RETURN(ret == 0); - - nfds = kdbus_item_get_nfds(msg); - ASSERT_RETURN(nfds == KDBUS_MSG_MAX_MEMFD_ITEMS); - + ASSERT_ZERO(kdbus_msg_recv(conn_dst, &msg, NULL)); + /* retransmission of memfds from before - roll back the counter before checking */ + value_checked_in -= ELEMENTSOF(memfds); + CHECK_MEMFDS(memfds, KDBUS_MSG_MAX_MEMFD_ITEMS, msg); kdbus_msg_free(msg); - ret = kdbus_msg_recv(conn_dst, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn_dst, NULL, NULL)); - for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++) - close(fds[i]); - - for (i = 0; i < KDBUS_MSG_MAX_ITEMS + 1; i++) - close(memfds[i]); + CLOSE_FDS(fds); + CLOSE_FDS(memfds); return 0; } -int kdbus_test_fd_passing(struct kdbus_test_env *env) +wur int kdbus_test_fd_passing(struct kdbus_test_env *env) { struct kdbus_conn *conn_src, *conn_dst; const char *str = "stackenblocken"; @@ -668,53 +658,56 @@ int kdbus_test_fd_passing(struct kdbus_test_env *env) now = (uint64_t) time(NULL); /* create two connections */ - conn_src = kdbus_hello(env->buspath, 0, NULL, 0); - conn_dst = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_src && conn_dst); + ASSERT_NONZERO(conn_src = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(conn_dst = kdbus_hello(env->buspath, 0, NULL, 0)); fds_conn[0] = conn_src->fd; fds_conn[1] = conn_dst->fd; - ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock_pair); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_pair)); /* Setup memfd */ memfd = memfd_write("memfd-name", &now, sizeof(now)); - ASSERT_RETURN(memfd >= 0); + ASSERT_RETURN(memfd,>=,0); /* Setup pipes */ - ret = pipe(fds); - ASSERT_RETURN(ret == 0); + while ((ret = pipe(fds))) /* work around intermittent pipe failure on tizen 3.0 */ + sleep(1); + ASSERT_ZERO(ret); i = write(fds[1], str, strlen(str)); - ASSERT_RETURN(i == strlen(str)); + ASSERT_RETURN(i,==,strlen(str)); /* - * Try to ass the handle of a connection as message payload. + * Try to pass the handle of a connection as message payload. * This must fail. */ - ret = send_fds(conn_src, conn_dst->id, fds_conn, 2); - ASSERT_RETURN(ret == -ENOTSUP); - - ret = send_fds(conn_dst, conn_src->id, fds_conn, 2); - ASSERT_RETURN(ret == -ENOTSUP); + ASSERT_RETURN(-ENOTSUP,==,send_fds(conn_src, conn_dst->id, fds_conn, 2)); + ASSERT_RETURN(-ENOTSUP,==,send_fds(conn_dst, conn_src->id, fds_conn, 2)); - ret = send_fds(conn_src, conn_dst->id, sock_pair, 2); - ASSERT_RETURN(ret == -ENOTSUP); + /* + * Tizen: socket passing is allowed. + */ + ASSERT_ZERO(send_fds(conn_src, conn_dst->id, sock_pair, 2)); + ASSERT_ZERO(kdbus_msg_recv(conn_dst, &msg, NULL)); + KDBUS_ITEM_FOREACH(item, msg, items) + if (item->type == KDBUS_ITEM_FDS) { + int nfds = (item->size - KDBUS_ITEM_HEADER_SIZE) / + sizeof(int); + ASSERT_RETURN(nfds,==,2); + } + kdbus_msg_free(msg); /* * Send fds and memfds to connection that do not accept fds */ - ret = kdbus_test_no_fds(env, fds, (int *)&memfd); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_test_no_fds(env, fds, (int *)&memfd)); /* Try to broadcast file descriptors. This must fail. */ - ret = send_fds(conn_src, KDBUS_DST_ID_BROADCAST, fds, 1); - ASSERT_RETURN(ret == -ENOTUNIQ); + ASSERT_RETURN(-ENOTUNIQ,==,send_fds(conn_src, KDBUS_DST_ID_BROADCAST, fds, 1)); /* Try to broadcast memfd. This must succeed. */ - ret = send_memfds(conn_src, KDBUS_DST_ID_BROADCAST, (int *)&memfd, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_memfds(conn_src, KDBUS_DST_ID_BROADCAST, (int *)&memfd, 1)); /* Open code this loop */ loop_send_fds: @@ -722,27 +715,26 @@ loop_send_fds: /* * Send the read end of the pipe and close it. */ - ret = send_fds(conn_src, conn_dst->id, fds, 1); - ASSERT_RETURN(ret == 0); - close(fds[0]); + ASSERT_ZERO(send_fds(conn_src, conn_dst->id, fds, 1)); + CLOSE(fds[0]); - ret = kdbus_msg_recv(conn_dst, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(conn_dst, &msg, NULL)); KDBUS_ITEM_FOREACH(item, msg, items) { if (item->type == KDBUS_ITEM_FDS) { char tmp[14]; int nfds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof(int); - ASSERT_RETURN(nfds == 1); + ASSERT_RETURN(sizeof(tmp),==,strlen(str)); + ASSERT_RETURN(nfds,==,1); i = read(item->fds[0], tmp, sizeof(tmp)); if (i != 0) { - ASSERT_RETURN(i == sizeof(tmp)); - ASSERT_RETURN(memcmp(tmp, str, sizeof(tmp)) == 0); + ASSERT_RETURN(i,==,sizeof(tmp)); + ASSERT_ZERO(memcmp(tmp, str, sizeof(tmp))); /* Write EOF */ - close(fds[1]); + CLOSE(fds[1]); /* * Resend the read end of the pipe, @@ -759,7 +751,7 @@ loop_send_fds: * of the pipe, other references are * automatically closed just after send. */ - close(item->fds[0]); + CLOSE(item->fds[0]); } } @@ -769,18 +761,15 @@ loop_send_fds: * references to it. We assume the above since sender and * receiver are on the same process. */ - ret = send_fds(conn_src, conn_dst->id, fds, 1); - ASSERT_RETURN(ret == -EBADF); + ASSERT_RETURN(-EBADF,==,send_fds(conn_src, conn_dst->id, fds, 1)); /* Then we clear out received any data... */ - kdbus_msg_free(msg); - ret = kdbus_send_multiple_fds(conn_src, conn_dst); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_send_multiple_fds(conn_src, conn_dst)); - close(sock_pair[0]); - close(sock_pair[1]); - close(memfd); + CLOSE(sock_pair[0]); + CLOSE(sock_pair[1]); + CLOSE(memfd); kdbus_conn_free(conn_src); kdbus_conn_free(conn_dst); diff --git a/tools/testing/selftests/kdbus/test-free.c b/tools/testing/selftests/kdbus/test-free.c index f666da3..2ec652f 100644 --- a/tools/testing/selftests/kdbus/test-free.c +++ b/tools/testing/selftests/kdbus/test-free.c @@ -14,51 +14,98 @@ #include "kdbus-enum.h" #include "kdbus-test.h" -static int sample_ioctl_call(struct kdbus_test_env *env) +wur static int sample_ioctl_call(struct kdbus_test_env *env, unsigned *poff, unsigned *psize) { - int ret; + unsigned off, size; struct kdbus_cmd_list cmd_list = { - .flags = KDBUS_LIST_QUEUED, + .flags = KDBUS_LIST_UNIQUE, .size = sizeof(cmd_list), }; - ret = kdbus_cmd_list(env->conn->fd, &cmd_list); - ASSERT_RETURN(ret == 0); - /* DON'T FREE THIS SLICE OF MEMORY! */ + ASSERT_ZERO(kdbus_cmd_list(env->conn->fd, &cmd_list)); + + #define A(L,R) do { ASSERT_RETURN((typeof(L))(R),==,(R)); *p##L = L = (R); } while (0) + A(off, cmd_list.offset); + ASSERT_RETURN(off,<,POOL_SIZE); + A(size, ((struct kdbus_info *)((uintptr_t)env->conn->buf + off))->size); + #undef A + + ASSERT_RETURN(off+size,<,POOL_SIZE); + ASSERT_RETURN(off+size,>=,size); + ASSERT_RETURN(off+size,>,off); + ASSERT_ZERO(size % 8); + ASSERT_RETURN(size,>=,sizeof(struct kdbus_info)); + + /*print("off(%u) size(%u)\n", *offset, *size);*/ return TEST_OK; } +wur static int area_before(unsigned off_left, unsigned size_left, unsigned off_right) +{ + ASSERT_RETURN(off_left+size_left,<=,off_right); + return 0; +} + int kdbus_test_free(struct kdbus_test_env *env) { - int ret; struct kdbus_cmd_free cmd_free = {}; + unsigned offset[20], size[TABSIZE(offset)]; + unsigned i; /* free an unallocated buffer */ cmd_free.size = sizeof(cmd_free); cmd_free.flags = 0; cmd_free.offset = 0; - ret = kdbus_cmd_free(env->conn->fd, &cmd_free); - ASSERT_RETURN(ret == -ENXIO); + ASSERT_RETURN(-ENXIO,==,kdbus_cmd_free(env->conn->fd, &cmd_free)); /* free a buffer out of the pool's bounds */ cmd_free.size = sizeof(cmd_free); cmd_free.offset = POOL_SIZE + 1; - ret = kdbus_cmd_free(env->conn->fd, &cmd_free); - ASSERT_RETURN(ret == -ENXIO); + ASSERT_RETURN(-ENXIO,==,kdbus_cmd_free(env->conn->fd, &cmd_free)); /* * The user application is responsible for freeing the allocated * memory with the KDBUS_CMD_FREE ioctl, so let's test what happens * if we forget about it. + * + * Assert that memory areas don't overlap. */ - ret = sample_ioctl_call(env); - ASSERT_RETURN(ret == 0); + for (i=0; i=0; --j) { + if (offset[j] > off) { + ASSERT_ZERO(area_before(off,siz,offset[j])); + offset[j+1] = offset[j]; + size[j+1] = size[j]; + } else { + ASSERT_ZERO(area_before(offset[j],size[j],off)); + break; + } + } + ASSERT_RETURN(j+1,>=,0); + ASSERT_RETURN((unsigned)(j+1),<=,i); + offset[j+1] = off; + size[j+1] = siz; + } - ret = sample_ioctl_call(env); - ASSERT_RETURN(ret == 0); + /* attempt to free invalid offsets around the ones above to test the underlying allocator */ + { + unsigned j, last = offset[TABSIZE(offset)-1] + size[TABSIZE(offset)-1] + 1; + for (i=j=0; iconn->fd, &cmd_free)); + } + } return TEST_OK; } diff --git a/tools/testing/selftests/kdbus/test-match.c b/tools/testing/selftests/kdbus/test-match.c index 2360dc1..6c35baf 100644 --- a/tools/testing/selftests/kdbus/test-match.c +++ b/tools/testing/selftests/kdbus/test-match.c @@ -14,7 +14,7 @@ #include "kdbus-enum.h" #include "kdbus-test.h" -int kdbus_test_match_id_add(struct kdbus_test_env *env) +static wur int add_id_match_(struct kdbus_conn *conn, uint64_t flags, uint64_t notification_type, uint64_t id) { struct { struct kdbus_cmd_match cmd; @@ -24,135 +24,101 @@ int kdbus_test_match_id_add(struct kdbus_test_env *env) struct kdbus_notify_id_change chg; } item; } buf; - struct kdbus_conn *conn; - struct kdbus_msg *msg; - int ret; - memset(&buf, 0, sizeof(buf)); - buf.cmd.size = sizeof(buf); buf.cmd.cookie = 0xdeafbeefdeaddead; + buf.cmd.flags = flags; buf.item.size = sizeof(buf.item); - buf.item.type = KDBUS_ITEM_ID_ADD; - buf.item.chg.id = KDBUS_MATCH_ID_ANY; + buf.item.type = notification_type; + buf.item.chg.id = id; + ASSERT_ZERO(kdbus_cmd_match_add(conn->fd, &buf.cmd)); + return 0; +} +#define ADD_ID_MATCH(CONN,FLAGS,NOTIFICATION_TYPE,ID)\ + ASSERT_ZERO(add_id_match_((CONN),(FLAGS),KDBUS_ITEM_ID_##NOTIFICATION_TYPE,(ID))) + +wur int kdbus_test_match_id_add(struct kdbus_test_env *env) +{ + struct kdbus_conn *conn; + struct kdbus_msg *msg; /* match on id add */ - ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd); - ASSERT_RETURN(ret == 0); + ADD_ID_MATCH(env->conn, 0, ADD, KDBUS_MATCH_ID_ANY); /* create 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* 1st connection should have received a notification */ - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_NO_PENDING(env->conn); - ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_ADD); - ASSERT_RETURN(msg->items[0].id_change.id == conn->id); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_ID_ADD); + ASSERT_RETURN(msg->items[0].id_change.id,==,conn->id); kdbus_conn_free(conn); return TEST_OK; } -int kdbus_test_match_id_remove(struct kdbus_test_env *env) +wur int kdbus_test_match_id_remove(struct kdbus_test_env *env) { - struct { - struct kdbus_cmd_match cmd; - struct { - uint64_t size; - uint64_t type; - struct kdbus_notify_id_change chg; - } item; - } buf; struct kdbus_conn *conn; struct kdbus_msg *msg; size_t id; - int ret; /* create 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); id = conn->id; - memset(&buf, 0, sizeof(buf)); - buf.cmd.size = sizeof(buf); - buf.cmd.cookie = 0xdeafbeefdeaddead; - buf.item.size = sizeof(buf.item); - buf.item.type = KDBUS_ITEM_ID_REMOVE; - buf.item.chg.id = id; - - /* register match on 2nd connection */ - ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd); - ASSERT_RETURN(ret == 0); + /* register match on 1st connection */ + ADD_ID_MATCH(env->conn, 0, REMOVE, id); /* remove 2nd connection again */ kdbus_conn_free(conn); /* 1st connection should have received a notification */ - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); - ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_REMOVE); - ASSERT_RETURN(msg->items[0].id_change.id == id); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_ID_REMOVE); + ASSERT_RETURN(msg->items[0].id_change.id,==,id); return TEST_OK; } -int kdbus_test_match_replace(struct kdbus_test_env *env) +wur int kdbus_test_match_replace(struct kdbus_test_env *env) { - struct { - struct kdbus_cmd_match cmd; - struct { - uint64_t size; - uint64_t type; - struct kdbus_notify_id_change chg; - } item; - } buf; struct kdbus_conn *conn; struct kdbus_msg *msg; size_t id; - int ret; /* add a match to id_add */ - ASSERT_RETURN(kdbus_test_match_id_add(env) == TEST_OK); + ASSERT_RETURN(kdbus_test_match_id_add(env),==,TEST_OK); /* do a replace of the match from id_add to id_remove */ - memset(&buf, 0, sizeof(buf)); - - buf.cmd.size = sizeof(buf); - buf.cmd.cookie = 0xdeafbeefdeaddead; - buf.cmd.flags = KDBUS_MATCH_REPLACE; - buf.item.size = sizeof(buf.item); - buf.item.type = KDBUS_ITEM_ID_REMOVE; - buf.item.chg.id = KDBUS_MATCH_ID_ANY; - - ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd); + ADD_ID_MATCH(env->conn, KDBUS_MATCH_REPLACE, REMOVE, KDBUS_MATCH_ID_ANY); /* create 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); id = conn->id; /* 1st connection should _not_ have received a notification */ - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret != 0); + ASSERT_NONZERO(kdbus_msg_recv(env->conn, &msg, NULL)); /* remove 2nd connection */ kdbus_conn_free(conn); /* 1st connection should _now_ have received a notification */ - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); - ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_REMOVE); - ASSERT_RETURN(msg->items[0].id_change.id == id); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_ID_REMOVE); + ASSERT_RETURN(msg->items[0].id_change.id,==,id); return TEST_OK; } -int kdbus_test_match_name_add(struct kdbus_test_env *env) +#define UNMATCHED_NAME "this.will.never.match" + +static wur int add_name_match_(struct kdbus_conn *conn, uint64_t flags, uint64_t old_id, uint64_t new_id, uint64_t notification_type, char const *name) { struct { struct kdbus_cmd_match cmd; @@ -163,152 +129,203 @@ int kdbus_test_match_name_add(struct kdbus_test_env *env) } item; char name[64]; } buf; - struct kdbus_msg *msg; - char *name; - int ret; - - name = "foo.bla.blaz"; - - /* install the match rule */ memset(&buf, 0, sizeof(buf)); - buf.item.type = KDBUS_ITEM_NAME_ADD; - buf.item.chg.old_id.id = KDBUS_MATCH_ID_ANY; - buf.item.chg.new_id.id = KDBUS_MATCH_ID_ANY; - strncpy(buf.name, name, sizeof(buf.name) - 1); - buf.item.size = sizeof(buf.item) + strlen(buf.name) + 1; + buf.cmd.flags = flags; + buf.cmd.cookie = 0xdeaddeaddeafbeef; + buf.item.type = notification_type; + buf.item.chg.old_id.id = old_id; + buf.item.chg.new_id.id = new_id; + buf.item.size = sizeof(buf.item); + if (name) { + __auto_type name_size = strlen(name)+1; + memcpy(buf.name, name, name_size); + buf.item.size += name_size; + } buf.cmd.size = sizeof(buf.cmd) + buf.item.size; + ASSERT_ZERO(kdbus_cmd_match_add(conn->fd, &buf.cmd)); + return 0; +} +#define ADD_NAME_MATCH(CONN,FLAGS,OLD_ID,NEW_ID,NOTIFICATION_TYPE,NAME)\ + ASSERT_ZERO(add_name_match_((CONN),(FLAGS),(OLD_ID),(NEW_ID),KDBUS_ITEM_NAME_##NOTIFICATION_TYPE,(NAME))) - ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd); - ASSERT_RETURN(ret == 0); +static wur int assert_single_match_(struct kdbus_conn *conn, uint64_t old_id, uint64_t new_id, uint64_t notification_type, char const *name) +{ + struct kdbus_msg *msg; + ASSERT_ZERO(kdbus_msg_recv(conn, &msg, NULL)); + ASSERT_RETURN(msg->items[0].type,==,notification_type); + ASSERT_RETURN(msg->items[0].name_change.old_id.id,==,old_id); + ASSERT_RETURN(msg->items[0].name_change.new_id.id,==,new_id); + ASSERT_ZERO(strcmp(msg->items[0].name_change.name, name)); + ASSERT_ZERO(kdbus_free_msg(conn, msg)); + ASSERT_NO_PENDING(conn); + return 0; +} +#define ASSERT_SINGLE_MATCH(CONN,OLD_ID,NEW_ID,NOTIFICATION_TYPE,NAME)\ + ASSERT_ZERO(assert_single_match_((CONN),(OLD_ID),(NEW_ID),KDBUS_ITEM_NAME_##NOTIFICATION_TYPE,(NAME))) +static wur int kdbus_test_match_name_add_(struct kdbus_test_env *env, char const *name, struct kdbus_conn *listener) +{ /* acquire the name */ - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, NULL)); - /* we should have received a notification */ - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + #define CHECK(CONN) ASSERT_SINGLE_MATCH((CONN), 0, env->conn->id, ADD, name) + CHECK(env->conn); + if (listener) + CHECK(listener); + #undef CHECK - ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_ADD); - ASSERT_RETURN(msg->items[0].name_change.old_id.id == 0); - ASSERT_RETURN(msg->items[0].name_change.new_id.id == env->conn->id); - ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0); + ASSERT_ZERO(kdbus_name_release(env->conn, name)); - return TEST_OK; + return 0; } -int kdbus_test_match_name_remove(struct kdbus_test_env *env) +wur int kdbus_test_match_name_add(struct kdbus_test_env *env) { - struct { - struct kdbus_cmd_match cmd; - struct { - uint64_t size; - uint64_t type; - struct kdbus_notify_name_change chg; - } item; - char name[64]; - } buf; - struct kdbus_msg *msg; - char *name; - int ret; + struct kdbus_conn *listener; + char const *name = "foo.bla.blaz"; - name = "foo.bla.blaz"; - - /* acquire the name */ - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_NONZERO(listener = kdbus_hello(env->buspath, 0, NULL, 0)); /* install the match rule */ - memset(&buf, 0, sizeof(buf)); - buf.item.type = KDBUS_ITEM_NAME_REMOVE; - buf.item.chg.old_id.id = KDBUS_MATCH_ID_ANY; - buf.item.chg.new_id.id = KDBUS_MATCH_ID_ANY; - strncpy(buf.name, name, sizeof(buf.name) - 1); - buf.item.size = sizeof(buf.item) + strlen(buf.name) + 1; - buf.cmd.size = sizeof(buf.cmd) + buf.item.size; + ADD_NAME_MATCH(env->conn, 0, KDBUS_MATCH_ID_ANY, KDBUS_MATCH_ID_ANY, ADD, name); + + /* no accidental notifications when no match set up */ + ASSERT_ZERO(kdbus_test_match_name_add_(env, name, NULL)); + ASSERT_NO_PENDING(listener); + + #define CHECK(ID,NAME,CONN_IF_WILL_MATCH) do {\ + ADD_NAME_MATCH(listener, KDBUS_MATCH_REPLACE, KDBUS_MATCH_ID_ANY, (ID), ADD, NAME);\ + ASSERT_ZERO(kdbus_test_match_name_add_(env, name, (CONN_IF_WILL_MATCH)));\ + ASSERT_NO_PENDING(listener);\ + } while (0) + CHECK(KDBUS_MATCH_ID_ANY, UNMATCHED_NAME, NULL); /* wrong name */ + CHECK(KDBUS_MATCH_ID_ANY, NULL, listener); /* wildcard name */ + CHECK(env->conn->id, NULL, listener); /* wildcard name + good id */ + CHECK(env->conn->id + 1, NULL, NULL); /* wildcard name + bad id */ + #undef CHECK + kdbus_conn_free(listener); - ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd); - ASSERT_RETURN(ret == 0); + return 0; +} + +static wur int kdbus_test_match_name_remove_(struct kdbus_test_env *env, char const *name, struct kdbus_conn *listener) +{ + /* acquire the name */ + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, NULL)); /* release the name again */ - kdbus_name_release(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_release(env->conn, name)); /* we should have received a notification */ - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + #define CHECK(CONN) ASSERT_SINGLE_MATCH((CONN), env->conn->id, 0, REMOVE, name) + CHECK(env->conn); + if (listener) + CHECK(listener); + #undef CHECK - ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_REMOVE); - ASSERT_RETURN(msg->items[0].name_change.old_id.id == env->conn->id); - ASSERT_RETURN(msg->items[0].name_change.new_id.id == 0); - ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0); - - return TEST_OK; + return 0; } -int kdbus_test_match_name_change(struct kdbus_test_env *env) +wur int kdbus_test_match_name_remove(struct kdbus_test_env *env) { - struct { - struct kdbus_cmd_match cmd; - struct { - uint64_t size; - uint64_t type; - struct kdbus_notify_name_change chg; - } item; - char name[64]; - } buf; - struct kdbus_conn *conn; - struct kdbus_msg *msg; - uint64_t flags; - char *name = "foo.bla.baz"; - int ret; + struct kdbus_conn *listener; + char const *name = "foo.bla.blazz"; - /* acquire the name */ - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_NONZERO(listener = kdbus_hello(env->buspath, 0, NULL, 0)); /* install the match rule */ - memset(&buf, 0, sizeof(buf)); - buf.item.type = KDBUS_ITEM_NAME_CHANGE; - buf.item.chg.old_id.id = KDBUS_MATCH_ID_ANY; - buf.item.chg.new_id.id = KDBUS_MATCH_ID_ANY; - strncpy(buf.name, name, sizeof(buf.name) - 1); - buf.item.size = sizeof(buf.item) + strlen(buf.name) + 1; - buf.cmd.size = sizeof(buf.cmd) + buf.item.size; + ADD_NAME_MATCH(env->conn, 0, KDBUS_MATCH_ID_ANY, KDBUS_MATCH_ID_ANY, REMOVE, name); + + /* no accidental notifications when no match set up */ + ASSERT_ZERO(kdbus_test_match_name_remove_(env, name, NULL)); + ASSERT_NO_PENDING(listener); + + #define CHECK(ID,NAME,CONN_IF_WILL_MATCH) do {\ + ADD_NAME_MATCH(listener, KDBUS_MATCH_REPLACE, (ID), KDBUS_MATCH_ID_ANY, REMOVE, NAME);\ + ASSERT_ZERO(kdbus_test_match_name_remove_(env, name, (CONN_IF_WILL_MATCH)));\ + ASSERT_NO_PENDING(listener);\ + } while (0) + CHECK(KDBUS_MATCH_ID_ANY, UNMATCHED_NAME, NULL); /* wrong name */ + CHECK(KDBUS_MATCH_ID_ANY, NULL, listener); /* wildcard name */ + CHECK(env->conn->id, NULL, listener); /* wildcard name + good id */ + CHECK(env->conn->id + 1, NULL, NULL); /* wildcard name + bad id */ + #undef CHECK + kdbus_conn_free(listener); - ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd); - ASSERT_RETURN(ret == 0); + return 0; +} - /* create a 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); +static wur int kdbus_test_match_name_change_(struct kdbus_test_env *env, struct kdbus_conn *conn, char const *name, struct kdbus_conn *listener) +{ + uint64_t flags; + + /* acquire the name */ + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, NULL)); /* allow the new connection to own the same name */ /* queue the 2nd connection as waiting owner */ flags = KDBUS_NAME_QUEUE; - ret = kdbus_name_acquire(conn, name, &flags); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(flags & KDBUS_NAME_IN_QUEUE); + ASSERT_ZERO(kdbus_name_acquire(conn, name, &flags)); + ASSERT_NONZERO(flags & KDBUS_NAME_IN_QUEUE); /* release name from 1st connection */ - ret = kdbus_name_release(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_release(env->conn, name)); /* we should have received a notification */ - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); + #define CHECK(CONN) ASSERT_SINGLE_MATCH((CONN), env->conn->id, conn->id, CHANGE, name) + CHECK(env->conn); + if (listener) + CHECK(listener); + #undef CHECK + + ASSERT_ZERO(kdbus_name_release(conn, name)); + + return 0; +} + +wur int kdbus_test_match_name_change(struct kdbus_test_env *env) +{ + struct kdbus_conn *listener, *conn; + char const *name = "foo.bla.baz"; + + /* create a 2nd connection */ + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); + + ASSERT_NONZERO(listener = kdbus_hello(env->buspath, 0, NULL, 0)); + + ADD_NAME_MATCH(env->conn, 0, KDBUS_MATCH_ID_ANY, KDBUS_MATCH_ID_ANY, CHANGE, name); + + /* no accidental notifications when no match set up */ + ASSERT_ZERO(kdbus_test_match_name_change_(env, conn, name, NULL)); + ASSERT_NO_PENDING(listener); + + #define CHECK(OLD_ID,NEW_ID,NAME,CONN_IF_WILL_MATCH) do {\ + ADD_NAME_MATCH(listener, KDBUS_MATCH_REPLACE, (OLD_ID), (NEW_ID), CHANGE, NAME);\ + ASSERT_ZERO(kdbus_test_match_name_change_(env, conn, name, (CONN_IF_WILL_MATCH)));\ + ASSERT_NO_PENDING(listener);\ + } while (0) + CHECK(KDBUS_MATCH_ID_ANY, KDBUS_MATCH_ID_ANY, UNMATCHED_NAME, NULL); /* wrong name */ + CHECK(KDBUS_MATCH_ID_ANY, KDBUS_MATCH_ID_ANY, NULL, listener); /* wildcard name */ + + CHECK(env->conn->id, KDBUS_MATCH_ID_ANY, NULL, listener); /* wildcard name + good id */ + CHECK(env->conn->id + 1, KDBUS_MATCH_ID_ANY, NULL, NULL); /* wildcard name + bad id */ + + CHECK(KDBUS_MATCH_ID_ANY, conn->id, NULL, listener); /* good id */ + CHECK(KDBUS_MATCH_ID_ANY, conn->id + 1, NULL, NULL); /* bad id */ - ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_CHANGE); - ASSERT_RETURN(msg->items[0].name_change.old_id.id == env->conn->id); - ASSERT_RETURN(msg->items[0].name_change.new_id.id == conn->id); - ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0); + CHECK(env->conn->id, conn->id, NULL, listener); /* wildcard name + good id */ + CHECK(env->conn->id + 1, conn->id, NULL, NULL); /* wildcard name + bad id */ + CHECK(env->conn->id, conn->id + 1, NULL, NULL); /* wildcard name + bad id */ + #undef CHECK + kdbus_conn_free(listener); + ASSERT_NO_PENDING(conn); kdbus_conn_free(conn); - return TEST_OK; + return 0; } -static int send_bloom_filter(const struct kdbus_conn *conn, +static wur int send_bloom_filter(const struct kdbus_conn *conn, uint64_t cookie, const uint8_t *filter, size_t filter_size, @@ -353,7 +370,7 @@ static int send_bloom_filter(const struct kdbus_conn *conn, return 0; } -int kdbus_test_match_bloom(struct kdbus_test_env *env) +wur int kdbus_test_match_bloom(struct kdbus_test_env *env) { struct { struct kdbus_cmd_match cmd; @@ -368,7 +385,6 @@ int kdbus_test_match_bloom(struct kdbus_test_env *env) struct kdbus_msg *msg; uint64_t cookie = 0xf000f00f; uint8_t filter[64]; - int ret; /* install the match rule */ memset(&buf, 0, sizeof(buf)); @@ -382,60 +398,183 @@ int kdbus_test_match_bloom(struct kdbus_test_env *env) buf.item.data_gen1[1] = 0xaa; buf.item.data_gen1[9] = 0x02; - ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_match_add(env->conn->fd, &buf.cmd)); /* create a 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* a message with a 0'ed out filter must not reach the other peer */ memset(filter, 0, sizeof(filter)); - ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0)); - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(env->conn, &msg, NULL)); /* now set the filter to the connection's mask and expect success */ filter[0] = 0x55; filter[63] = 0x80; - ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0)); - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); /* broaden the filter and try again. this should also succeed. */ filter[0] = 0xff; filter[8] = 0xff; filter[63] = 0xff; - ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0)); - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); /* the same filter must not match against bloom generation 1 */ - ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 1)); - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(env->conn, &msg, NULL)); /* set a different filter and try again */ filter[1] = 0xaa; filter[9] = 0x02; - ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 1)); - ret = kdbus_msg_recv(env->conn, &msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_conn_free(conn); return TEST_OK; } + +static wur int has_all_names(struct kdbus_item *item, unsigned size) +{ + char seen[256]; + int left = sizeof(seen); + memset(seen, 0, sizeof(seen)); + + while (size && left) { + uint64_t item_size = KDBUS_ALIGN8(item->size); + if (item_size > size) + return -1; + if (KDBUS_ITEM_OWNED_NAME == item->type) { + int i; + ASSERT_RETURN(255u,==,strlen(item->name.name)); + ASSERT_RETURN(0,==,memcmp(item->name.name, "big.n", 5)); + for (i=5;i<252;++i) + ASSERT_RETURN('0',==,(int)item->name.name[i]); + ASSERT_RETURN('0',<=,(int)item->name.name[252]); + ASSERT_RETURN((int)item->name.name[252],<=,'9'); + ASSERT_RETURN('0',<=,(int)item->name.name[253]); + ASSERT_RETURN((int)item->name.name[253],<=,'9'); + ASSERT_RETURN('0',<=,(int)item->name.name[254]); + ASSERT_RETURN((int)item->name.name[254],<=,'9'); + i = item->name.name[254]-'0' + 10*(item->name.name[253]-'0') + 100*(item->name.name[252]-'0'); + ASSERT_RETURN(0,<=,i); + ASSERT_RETURN(i,<,256); + ASSERT_ZERO((int)seen[i]); + seen[i] = 1; + --left; + } + size -= (unsigned)item_size; + item = (typeof(item))((uintptr_t)item + (unsigned)item_size); + } + + return left; +} + +wur int kdbus_test_big_metadata(struct kdbus_test_env *env) +{ + uint64_t offset; + struct kdbus_conn *conn; + struct kdbus_msg *msg; + struct kdbus_info *info; + int i; + char buf[256]; + + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); + for (i=256; --i>=0;) { + sprintf(buf, "big.n%0250d", i); + /*print("\nreg (%s)\n", buf);*/ + ASSERT_ZERO(kdbus_name_acquire(conn, buf, NULL)); + } + + /*print("\nreg done\n");*/ + + ASSERT_ZERO(kdbus_msg_send(conn, NULL, 1, 0, 0, 0, env->conn->id)); + /*print("\nsend done\n");*/ + /*print("\nfree done\n");*/ + + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + /*print("\nrecv done\n");*/ + + ASSERT_ZERO(has_all_names(msg->items, msg->size - offsetof(typeof(*msg), items))); + + kdbus_msg_free(msg); + + ASSERT_ZERO(kdbus_conn_info(env->conn, conn->id, NULL, _KDBUS_ATTACH_ALL, &offset)); + info = (struct kdbus_info *)(env->conn->buf + offset); + ASSERT_RETURN(info->id,==,conn->id); + ASSERT_ZERO(has_all_names(info->items, info->size - offsetof(typeof(*info), items))); + + kdbus_conn_free(conn); + + /*print("\nfree done\n");*/ + + return TEST_OK; +} + +wur int kdbus_test_match_itemless(struct kdbus_test_env *env) +{ + struct kdbus_cmd_match cmd; + struct kdbus_conn *conn; + struct kdbus_msg *msg; + uint64_t cookie = 0xf000f00f; + uint8_t filter[64]; + + /* install the match rule */ + memset(&cmd, 0, sizeof(cmd)); + cmd.size = sizeof(cmd); + + ASSERT_ZERO(kdbus_cmd_match_add(env->conn->fd, &cmd)); + + /* create a 2nd connection */ + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); + + /* 1st connection should have received a notification */ + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_NO_PENDING(env->conn); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_ID_ADD); + ASSERT_RETURN(msg->items[0].id_change.id,==,conn->id); + + /* even a message with a 0'ed out filter must match */ + memset(filter, 0, sizeof(filter)); + ASSERT_ZERO(send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0)); + + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_NO_PENDING(env->conn); + ASSERT_RETURN(msg->cookie,==,cookie); + + ASSERT_ZERO(kdbus_name_acquire(conn, "mein.volk", NULL)); + /* 1st connection should have received a notification */ + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_NO_PENDING(env->conn); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_NAME_ADD); + ASSERT_RETURN(msg->items[0].name_change.new_id.id,==,conn->id); + + ASSERT_ZERO(kdbus_name_release(conn, "mein.volk")); + /* 1st connection should have received a notification */ + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_NO_PENDING(env->conn); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_NAME_REMOVE); + ASSERT_RETURN(msg->items[0].name_change.old_id.id,==,conn->id); + + kdbus_conn_free(conn); + + /* 1st connection should have received a notification */ + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + ASSERT_NO_PENDING(env->conn); + ASSERT_RETURN(msg->items[0].type,==,(typeof(msg->items[0].type))KDBUS_ITEM_ID_REMOVE); + ASSERT_RETURN(msg->items[0].id_change.id,==,conn->id); + + ASSERT_NO_PENDING(env->conn); + + return TEST_OK; +} diff --git a/tools/testing/selftests/kdbus/test-message.c b/tools/testing/selftests/kdbus/test-message.c index d9b8fbd..aa12118 100644 --- a/tools/testing/selftests/kdbus/test-message.c +++ b/tools/testing/selftests/kdbus/test-message.c @@ -19,63 +19,54 @@ #include "kdbus-test.h" /* maximum number of queued messages from the same individual user */ -#define KDBUS_CONN_MAX_MSGS 256 +#define KDBUS_CONN_MAX_MSGS 256U /* maximum number of queued requests waiting for a reply */ -#define KDBUS_CONN_MAX_REQUESTS_PENDING 128 +#define KDBUS_CONN_MAX_REQUESTS_PENDING 1024U /* maximum message payload size */ #define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE (2 * 1024UL * 1024UL) -int kdbus_test_message_basic(struct kdbus_test_env *env) +wur int kdbus_test_message_basic(struct kdbus_test_env *env) { struct kdbus_conn *conn; struct kdbus_conn *sender; struct kdbus_msg *msg; uint64_t cookie = 0x1234abcd5678eeff; uint64_t offset; - int ret; - sender = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(sender != NULL); + ASSERT_NONZERO(sender = kdbus_hello(env->buspath, 0, NULL, 0)); /* create a 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_add_match_empty(conn); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn)); - ret = kdbus_add_match_empty(sender); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(sender)); /* send over 1st connection */ - ret = kdbus_msg_send(sender, NULL, cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(sender, NULL, cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); - /* Make sure that we do not get our own broadcasts */ - ret = kdbus_msg_recv(sender, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + /* Make sure that we do get our own broadcasts */ + ASSERT_ZERO(kdbus_msg_recv(sender, &msg, &offset)); + ASSERT_RETURN(msg->cookie,==,cookie); + kdbus_msg_free(msg); /* ... and receive on the 2nd */ - ret = kdbus_msg_recv_poll(conn, 100, &msg, &offset); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv_poll(conn, 100, &msg, &offset)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); /* Msgs that expect a reply must have timeout and cookie */ - ret = kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY, - 0, 0, conn->id, 0, NULL); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY, 1000000000, 0, conn->id)); /* no cookie */ + ASSERT_RETURN(-EINVAL,==,kdbus_msg_send(sender, NULL, 1, KDBUS_MSG_EXPECT_REPLY, 0, 0, conn->id)); /* no timeout */ + ASSERT_RETURN(-EINVAL,==,kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY, 0, 0, conn->id)); /* neither cookie nor timeout */ - /* Faked replies with a valid reply cookie are rejected */ - ret = kdbus_msg_send_reply(conn, time(NULL) ^ cookie, sender->id); - ASSERT_RETURN(ret == -EPERM); + /* Faked replies with a valid reply cookie are rejected iff not TIZEN */ + ASSERT_RETURN(ONTIZEN(0,-EBADSLT),==,kdbus_msg_send_reply(conn, time(NULL) ^ cookie, sender->id)); - ret = kdbus_free(conn, offset); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_free(conn, offset)); kdbus_conn_free(sender); kdbus_conn_free(conn); @@ -83,7 +74,7 @@ int kdbus_test_message_basic(struct kdbus_test_env *env) return TEST_OK; } -static int msg_recv_prio(struct kdbus_conn *conn, +static wur int msg_recv_prio(struct kdbus_conn *conn, int64_t requested_prio, int64_t expected_prio) { @@ -93,7 +84,7 @@ static int msg_recv_prio(struct kdbus_conn *conn, .priority = requested_prio, }; struct kdbus_msg *msg; - int ret; + int ret, dumpret; ret = kdbus_cmd_recv(conn->fd, &recv); if (ret < 0) { @@ -102,7 +93,7 @@ static int msg_recv_prio(struct kdbus_conn *conn, } msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset); - kdbus_msg_dump(conn, msg); + dumpret = kdbus_msg_dump(msg); if (msg->priority != expected_prio) { kdbus_printf("expected message prio %lld, got %lld\n", @@ -115,54 +106,42 @@ static int msg_recv_prio(struct kdbus_conn *conn, ret = kdbus_free(conn, recv.msg.offset); if (ret < 0) return ret; + if (dumpret) + return dumpret; return 0; } -int kdbus_test_message_prio(struct kdbus_test_env *env) +wur int kdbus_test_message_prio(struct kdbus_test_env *env) { struct kdbus_conn *a, *b; uint64_t cookie = 0; - int ret; - a = kdbus_hello(env->buspath, 0, NULL, 0); - b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(a && b); - - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 25, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -600, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -35, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -100, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 20, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -15, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -150, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -10, a->id, 0, NULL); - ASSERT_RETURN(ret == 0); - - ASSERT_RETURN(msg_recv_prio(a, -200, -800) == 0); - ASSERT_RETURN(msg_recv_prio(a, -100, -800) == 0); - ASSERT_RETURN(msg_recv_prio(a, -400, -600) == 0); - ASSERT_RETURN(msg_recv_prio(a, -400, -600) == -EAGAIN); - ASSERT_RETURN(msg_recv_prio(a, 10, -150) == 0); - ASSERT_RETURN(msg_recv_prio(a, 10, -100) == 0); + ASSERT_NONZERO(a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(b = kdbus_hello(env->buspath, 0, NULL, 0)); + + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 25, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -600, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -35, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -100, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 20, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -15, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -150, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id)); + ASSERT_ZERO(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -10, a->id)); + + ASSERT_ZERO(msg_recv_prio(a, -200, -800)); + ASSERT_ZERO(msg_recv_prio(a, -100, -800)); + ASSERT_ZERO(msg_recv_prio(a, -400, -600)); + ASSERT_RETURN(msg_recv_prio(a, -400, -600),==,-EAGAIN); + ASSERT_ZERO(msg_recv_prio(a, 10, -150)); + ASSERT_ZERO(msg_recv_prio(a, 10, -100)); kdbus_printf("--- get priority (all)\n"); - ASSERT_RETURN(kdbus_msg_recv(a, NULL, NULL) == 0); + ASSERT_ZERO(kdbus_msg_recv(a, NULL, NULL)); kdbus_conn_free(a); kdbus_conn_free(b); @@ -170,37 +149,26 @@ int kdbus_test_message_prio(struct kdbus_test_env *env) return TEST_OK; } -static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env) +static wur int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env) { - int ret; unsigned int i; struct kdbus_conn *conn; struct kdbus_conn *reader; struct kdbus_msg *msg = NULL; struct kdbus_cmd_recv recv = { .size = sizeof(recv) }; - reader = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(reader); - - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(reader = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* Register for ID signals */ - ret = kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD, - KDBUS_MATCH_ID_ANY); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD, KDBUS_MATCH_ID_ANY)); - ret = kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE, - KDBUS_MATCH_ID_ANY); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE, KDBUS_MATCH_ID_ANY)); /* Each iteration two notifications: add and remove ID */ for (i = 0; i < KDBUS_CONN_MAX_MSGS / 2; i++) { struct kdbus_conn *notifier; - - notifier = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(notifier); - + ASSERT_NONZERO(notifier = kdbus_hello(env->buspath, 0, NULL, 0)); kdbus_conn_free(notifier); } @@ -208,15 +176,12 @@ static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env) * Now the reader queue is full with kernel notfications, * but as a user we still have room to push our messages. */ - ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id, - 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id)); /* More ID kernel notifications that will be lost */ kdbus_conn_free(conn); - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); kdbus_conn_free(conn); @@ -224,10 +189,9 @@ static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env) * We lost only 3 packets since only signal msgs are * accounted. The connection ID add/remove notification */ - ret = kdbus_cmd_recv(reader->fd, &recv); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS); - ASSERT_RETURN(recv.dropped_msgs == 3); + ASSERT_ZERO(kdbus_cmd_recv(reader->fd, &recv)); + ASSERT_NONZERO(recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS); + ASSERT_RETURN(recv.dropped_msgs,==,3U); msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset); kdbus_msg_free(msg); @@ -237,20 +201,16 @@ static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env) memset(&recv, 0, sizeof(recv)); recv.size = sizeof(recv); - ret = kdbus_cmd_recv(reader->fd, &recv); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(!(recv.return_flags & - KDBUS_RECV_RETURN_DROPPED_MSGS)); + ASSERT_ZERO(kdbus_cmd_recv(reader->fd, &recv)); + ASSERT_ZERO(recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS); msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset); kdbus_msg_free(msg); } - ret = kdbus_msg_recv(reader, NULL, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv(reader, NULL, NULL)); - ret = kdbus_msg_recv(reader, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(reader, NULL, NULL)); kdbus_conn_free(reader); @@ -258,7 +218,7 @@ static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env) } /* Return the number of message successfully sent */ -static int kdbus_fill_conn_queue(struct kdbus_conn *conn_src, +static wur int kdbus_fill_conn_queue(struct kdbus_conn *conn_src, uint64_t dst_id, unsigned int max_msgs) { @@ -271,7 +231,7 @@ static int kdbus_fill_conn_queue(struct kdbus_conn *conn_src, size = sizeof(struct kdbus_msg); msg = malloc(size); - ASSERT_RETURN_VAL(msg, -ENOMEM); + ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM); memset(msg, 0, size); msg->size = size; @@ -283,10 +243,12 @@ static int kdbus_fill_conn_queue(struct kdbus_conn *conn_src, cmd.msg_address = (uintptr_t)msg; for (i = 0; i < max_msgs; i++) { - msg->cookie = cookie++; + msg->cookie = ++cookie; ret = kdbus_cmd_send(conn_src->fd, &cmd); - if (ret < 0) + if (ret < 0) { + /*print("fill_conn_queue_senderr(%d)", ret);*/ break; + } } free(msg); @@ -294,17 +256,15 @@ static int kdbus_fill_conn_queue(struct kdbus_conn *conn_src, return i; } -static int kdbus_test_activator_quota(struct kdbus_test_env *env) +wur int kdbus_test_activator_quota(struct kdbus_test_env *env) { - int ret; - unsigned int i; - unsigned int activator_msgs_count = 0; + unsigned i, activator_msgs_count=0; uint64_t cookie = time(NULL); + uint64_t flags = KDBUS_NAME_REPLACE_EXISTING; struct kdbus_conn *conn; struct kdbus_conn *sender; struct kdbus_conn *activator; struct kdbus_msg *msg; - uint64_t flags = KDBUS_NAME_REPLACE_EXISTING; struct kdbus_cmd_recv recv = { .size = sizeof(recv) }; struct kdbus_policy_access access = { .type = KDBUS_POLICY_ACCESS_USER, @@ -312,140 +272,110 @@ static int kdbus_test_activator_quota(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - activator = kdbus_hello_activator(env->buspath, "foo.test.activator", - &access, 1); - ASSERT_RETURN(activator); - - conn = kdbus_hello(env->buspath, 0, NULL, 0); - sender = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn || sender); - - ret = kdbus_list(sender, KDBUS_LIST_NAMES | - KDBUS_LIST_UNIQUE | - KDBUS_LIST_ACTIVATORS | - KDBUS_LIST_QUEUED); - ASSERT_RETURN(ret == 0); - - for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) { - ret = kdbus_msg_send(sender, "foo.test.activator", - cookie++, 0, 0, 0, - KDBUS_DST_ID_NAME, - 0, NULL); - if (ret < 0) - break; - activator_msgs_count++; - } + ASSERT_NONZERO(activator = kdbus_hello_activator(env->buspath, "foo.test.activator", &access, 1)); + + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(sender = kdbus_hello(env->buspath, 0, NULL, 0)); + + ASSERT_ZERO(kdbus_list(sender, KDBUS_LIST_NAMES | KDBUS_LIST_UNIQUE | KDBUS_LIST_ACTIVATORS | KDBUS_LIST_QUEUED)); + +#define EXHAUST(EXPECTERR,SENDOP) do {\ + for (i = 0;; ++i) {\ + int ret = (SENDOP);\ + ASSERT_RETURN(i,<=,KDBUS_CONN_MAX_MSGS);\ + if (0 > ret) {\ + ASSERT_RETURN((EXPECTERR),==,ret);\ + ASSERT_RETURN(i,<,KDBUS_CONN_MAX_MSGS);\ + break;\ + }\ + }\ +} while (0) + EXHAUST(-ENOBUFS,kdbus_msg_send(sender, "foo.test.activator", ++cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); + activator_msgs_count = i; /* we must have at least sent one message */ - ASSERT_RETURN_VAL(i > 0, -errno); - ASSERT_RETURN(ret == -ENOBUFS); + ASSERT_RETURN_VAL(i,>,0U, -errno); /* Good, activator queue is full now */ /* ENXIO on direct send (activators can never be addressed by ID) */ - ret = kdbus_msg_send(conn, NULL, cookie++, 0, 0, 0, activator->id, - 0, NULL); - ASSERT_RETURN(ret == -ENXIO); + ASSERT_RETURN(-ENXIO,==,kdbus_msg_send(conn, NULL, ++cookie, 0, 0, 0, activator->id)); /* can't queue more */ - ret = kdbus_msg_send(conn, "foo.test.activator", cookie++, - 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL); - ASSERT_RETURN(ret == -ENOBUFS); + ASSERT_RETURN(-ENOBUFS,==,kdbus_msg_send(conn, "foo.test.activator", ++cookie, 0, 0, 0, KDBUS_DST_ID_NAME)); /* no match installed, so the broadcast will not inc dropped_msgs */ - ret = kdbus_msg_send(sender, NULL, cookie++, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn, NULL, ++cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); /* Check activator queue */ - ret = kdbus_cmd_recv(activator->fd, &recv); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(recv.dropped_msgs == 0); - - activator_msgs_count--; + ASSERT_ZERO(kdbus_cmd_recv(activator->fd, &recv)); + ASSERT_ZERO(recv.dropped_msgs); msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset); + ASSERT_RETURN(msg->src_id,==,sender->id); + ASSERT_RETURN(msg->dst_id,==,(typeof(msg->dst_id))KDBUS_DST_ID_NAME); + --activator_msgs_count; kdbus_msg_free(msg); /* Stage 1) of test check the pool memory quota */ /* Consume the connection pool memory */ - for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) { - ret = kdbus_msg_send(sender, NULL, - cookie++, 0, 0, 0, conn->id, 0, NULL); - if (ret < 0) - break; - } + EXHAUST(-ENOBUFS,kdbus_msg_send(conn, NULL, ++cookie, 0, 0, 0, conn->id)); /* consume one message, so later at least one can be moved */ memset(&recv, 0, sizeof(recv)); recv.size = sizeof(recv); - ret = kdbus_cmd_recv(conn->fd, &recv); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(recv.dropped_msgs == 0); + ASSERT_ZERO(kdbus_cmd_recv(conn->fd, &recv)); + ASSERT_ZERO(recv.dropped_msgs); msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset); kdbus_msg_free(msg); /* Try to acquire the name now */ - ret = kdbus_name_acquire(conn, "foo.test.activator", &flags); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn, "foo.test.activator", &flags)); /* try to read messages and see if we have lost some */ memset(&recv, 0, sizeof(recv)); recv.size = sizeof(recv); - ret = kdbus_cmd_recv(conn->fd, &recv); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(recv.dropped_msgs != 0); + ASSERT_ZERO(kdbus_cmd_recv(conn->fd, &recv)); + ASSERT_NONZERO(recv.dropped_msgs); /* number of dropped msgs < received ones (at least one was moved) */ - ASSERT_RETURN(recv.dropped_msgs < activator_msgs_count); + ASSERT_RETURN(recv.dropped_msgs,<,activator_msgs_count); /* Deduct the number of dropped msgs from the activator msgs */ activator_msgs_count -= recv.dropped_msgs; msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset); kdbus_msg_free(msg); - /* * Release the name and hand it back to activator, now * we should have 'activator_msgs_count' msgs again in * the activator queue */ - ret = kdbus_name_release(conn, "foo.test.activator"); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_release(conn, "foo.test.activator")); /* make sure that we got our previous activator msgs */ - ret = kdbus_msg_recv(activator, &msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->src_id == sender->id); - - activator_msgs_count--; - + ASSERT_ZERO(kdbus_msg_recv(activator, &msg, NULL)); + ASSERT_RETURN(msg->src_id,==,sender->id); + ASSERT_RETURN(msg->dst_id,==,(typeof(msg->dst_id))KDBUS_DST_ID_NAME); + --activator_msgs_count; kdbus_msg_free(msg); /* Stage 2) of test check max message quota */ - /* Empty conn queue */ - for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) { - ret = kdbus_msg_recv(conn, NULL, NULL); - if (ret == -EAGAIN) - break; - } - - /* fill queue with max msgs quota */ - ret = kdbus_fill_conn_queue(sender, conn->id, KDBUS_CONN_MAX_MSGS); - ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS); + /* Empty conn queue and refill it to the brink anew */ + EXHAUST(-EAGAIN,kdbus_msg_recv(conn, NULL, NULL)); + EXHAUST(-ENOBUFS,kdbus_msg_send(sender, NULL, ++cookie, 0, 0, 0, conn->id)); +#undef EXHAUST - /* This one is lost but it is not accounted */ - ret = kdbus_msg_send(sender, NULL, - cookie++, 0, 0, 0, conn->id, 0, NULL); - ASSERT_RETURN(ret == -ENOBUFS); + if (!activator_msgs_count) + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(activator, NULL, NULL)); /* Acquire the name again */ - ret = kdbus_name_acquire(conn, "foo.test.activator", &flags); - ASSERT_RETURN(ret == 0); + flags = KDBUS_NAME_REPLACE_EXISTING; + ASSERT_ZERO(kdbus_name_acquire(conn, "foo.test.activator", &flags)); memset(&recv, 0, sizeof(recv)); recv.size = sizeof(recv); @@ -455,9 +385,8 @@ static int kdbus_test_activator_quota(struct kdbus_test_env *env) * the activator messages due to quota checks. Our queue is * already full. */ - ret = kdbus_cmd_recv(conn->fd, &recv); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(recv.dropped_msgs == activator_msgs_count); + ASSERT_ZERO(kdbus_cmd_recv(conn->fd, &recv)); + ASSERT_RETURN(recv.dropped_msgs,==,activator_msgs_count); msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset); kdbus_msg_free(msg); @@ -466,66 +395,114 @@ static int kdbus_test_activator_quota(struct kdbus_test_env *env) kdbus_conn_free(conn); kdbus_conn_free(activator); + return TEST_OK; +} + +#define TIMEOUT_CONNECTION_COUNT 8 +#define TIMEOUTS_PER_CONNECTION (MIN(KDBUS_CONN_MAX_REQUESTS_PENDING,KDBUS_CONN_MAX_MSGS)/TIMEOUT_CONNECTION_COUNT) + +static wur int kdbus_test_expected_reply_validate_timeouts(struct kdbus_conn *conn, uint64_t first_cookie, uint64_t type) +{ + uint64_t cookie_reply, seqnum, monotonic_ns, realtime_ns, prev_seqnum=0, prev_monotonic_ns=0, prev_realtime_ns=0; + unsigned i, next_cookie[TIMEOUT_CONNECTION_COUNT]; + memset(next_cookie, 0, sizeof(next_cookie)); + for (i=0; i < MIN(KDBUS_CONN_MAX_REQUESTS_PENDING,KDBUS_CONN_MAX_MSGS); i++) { + unsigned n, r; + ASSERT_ZERO(timeout_msg_recv(conn, type, &cookie_reply, &seqnum, &monotonic_ns, &realtime_ns)); + #define A(W,R) do { ASSERT_RETURN(prev_##W,R,W); prev_##W = W; } while (0); + A(seqnum,<) + A(monotonic_ns,<=) + A(realtime_ns,<=) + #undef A + ASSERT_RETURN(first_cookie,<=,cookie_reply); + cookie_reply -= first_cookie; + n = cookie_reply % TIMEOUT_CONNECTION_COUNT; + r = cookie_reply / TIMEOUT_CONNECTION_COUNT; + ASSERT_RETURN(r,==,next_cookie[n]); + ++next_cookie[n]; + } + ASSERT_NO_PENDING(conn); return 0; } -static int kdbus_test_expected_reply_quota(struct kdbus_test_env *env) +static wur int kdbus_test_expected_reply_timeouts_or_quota(struct kdbus_test_env *env) { - int ret; - unsigned int i, n; - unsigned int count; - uint64_t cookie = 0x1234abcd5678eeff; + unsigned i, n; + uint64_t first_cookie = 0x1234abcd5678eeff; struct kdbus_conn *conn; - struct kdbus_conn *connections[9]; + struct kdbus_conn *connections[1+TIMEOUT_CONNECTION_COUNT]; - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); - for (i = 0; i < 9; i++) { - connections[i] = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(connections[i]); - } + for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++) + ASSERT_NONZERO(connections[i] = kdbus_hello(env->buspath, 0, NULL, 0)); - count = 0; - /* Send 16 messages to 8 different connections */ - for (i = 0; i < 8; i++) { - for (n = 0; n < 16; n++) { - ret = kdbus_msg_send(conn, NULL, cookie++, - KDBUS_MSG_EXPECT_REPLY, - 100000000ULL, 0, - connections[i]->id, - 0, NULL); - if (ret < 0) - break; + _Static_assert(!(KDBUS_CONN_MAX_REQUESTS_PENDING%TIMEOUT_CONNECTION_COUNT), "KDBUS_CONN_MAX_REQUESTS_PENDING) not a multitude of TIMEOUT_CONNECTION_COUNT - quota test needs to be modified to reflect that"); - count++; + /* Send messages to TIMEOUT_CONNECTION_COUNT different connections */ + for (i = 0; i < TIMEOUT_CONNECTION_COUNT; i++) + for (n = 0; n < TIMEOUTS_PER_CONNECTION; n++) { + ASSERT_ZERO(kdbus_msg_send(conn, NULL, first_cookie + i + n*TIMEOUT_CONNECTION_COUNT, + KDBUS_MSG_EXPECT_REPLY, + 200000000ULL /* 0.2s */, 0, + connections[i]->id)); + /* drain queue to avoid hitting KDBUS_CONN_MAX_MSGS */ + ASSERT_ZERO(kdbus_msg_recv(connections[i], NULL, NULL)); } - } - /* - * We should have queued at least - * KDBUS_CONN_MAX_REQUESTS_PENDING method call - */ - ASSERT_RETURN(count == KDBUS_CONN_MAX_REQUESTS_PENDING); + sleep(1); /* just to wait and see if timeout logic somehow destabilizes the system */ + + ASSERT_ZERO(kdbus_test_expected_reply_validate_timeouts(conn, first_cookie, KDBUS_ITEM_REPLY_TIMEOUT)); + + for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++) + kdbus_conn_free(connections[i]); + + kdbus_conn_free(conn); + + return 0; +} + +static wur int kdbus_test_expected_reply_quota(struct kdbus_test_env *env) +{ + unsigned i, n; + uint64_t first_cookie = 0x5678eeff1234abcd; + struct kdbus_conn *conn; + struct kdbus_conn *connections[1+TIMEOUT_CONNECTION_COUNT]; + + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); + + for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++) + ASSERT_NONZERO(connections[i] = kdbus_hello(env->buspath, 0, NULL, 0)); + + /* Send messages to TIMEOUT_CONNECTION_COUNT different connections */ + for (i = 0; i < TIMEOUT_CONNECTION_COUNT; i++) + for (n = 0; n < KDBUS_CONN_MAX_REQUESTS_PENDING/TIMEOUT_CONNECTION_COUNT; n++) { + ASSERT_ZERO(kdbus_msg_send(conn, NULL, first_cookie + i + n*TIMEOUT_CONNECTION_COUNT, + KDBUS_MSG_EXPECT_REPLY, + KDBUS_TIMEOUT_INFINITE, 0, /* massive timeout to make sure all pending replies do not timeout before quota check below */ + connections[i]->id)); + /* drain queue to avoid hitting KDBUS_CONN_MAX_MSGS */ + ASSERT_ZERO(kdbus_msg_recv(connections[i], NULL, NULL)); + } /* * Now try to send a message to the last connection, * if we have reached KDBUS_CONN_MAX_REQUESTS_PENDING * no further requests are allowed */ - ret = kdbus_msg_send(conn, NULL, cookie++, KDBUS_MSG_EXPECT_REPLY, - 1000000000ULL, 0, connections[8]->id, 0, NULL); - ASSERT_RETURN(ret == -EMLINK); + ASSERT_RETURN(-EMLINK,==,kdbus_msg_send(conn, NULL, first_cookie + TIMEOUT_CONNECTION_COUNT*TIMEOUTS_PER_CONNECTION, KDBUS_MSG_EXPECT_REPLY, 1000000000ULL, 0, connections[TIMEOUT_CONNECTION_COUNT]->id)); - for (i = 0; i < 9; i++) + for (i = 0; i < 1+TIMEOUT_CONNECTION_COUNT; i++) kdbus_conn_free(connections[i]); + ASSERT_ZERO(kdbus_test_expected_reply_validate_timeouts(conn, first_cookie, KDBUS_ITEM_REPLY_DEAD)); + kdbus_conn_free(conn); return 0; } -int kdbus_test_pool_quota(struct kdbus_test_env *env) +wur int kdbus_test_pool_quota(struct kdbus_test_env *env) { struct kdbus_conn *a, *b, *c; struct kdbus_cmd_send cmd = {}; @@ -544,18 +521,17 @@ int kdbus_test_pool_quota(struct kdbus_test_env *env) return 0; payload = calloc(KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE, sizeof(char)); - ASSERT_RETURN_VAL(payload, -ENOMEM); + ASSERT_RETURN_VAL(payload,!=,NULL, -ENOMEM); - a = kdbus_hello(env->buspath, 0, NULL, 0); - b = kdbus_hello(env->buspath, 0, NULL, 0); - c = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(a && b && c); + ASSERT_NONZERO(a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(b = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(c = kdbus_hello(env->buspath, 0, NULL, 0)); size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); msg = malloc(size); - ASSERT_RETURN_VAL(msg, -ENOMEM); + ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM); memset(msg, 0, size); msg->size = size; @@ -583,34 +559,29 @@ int kdbus_test_pool_quota(struct kdbus_test_env *env) msg->cookie = cookie++; ret = kdbus_cmd_send(a->fd, &cmd); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); } /* Try to get more than 33% */ msg->cookie = cookie++; - ret = kdbus_cmd_send(a->fd, &cmd); - ASSERT_RETURN(ret == -ENOBUFS); + ASSERT_RETURN(-ENOBUFS,==,kdbus_cmd_send(a->fd, &cmd)); /* We still can pass small messages */ - ret = kdbus_msg_send(b, NULL, cookie++, 0, 0, 0, c->id, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(b, NULL, cookie++, 0, 0, 0, c->id)); for (i = size; i < (POOL_SIZE / 2 / 3); i += size) { - ret = kdbus_msg_recv(c, &recv_msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(recv_msg->src_id == a->id); + ASSERT_ZERO(kdbus_msg_recv(c, &recv_msg, NULL)); + ASSERT_RETURN(recv_msg->src_id,==,a->id); kdbus_msg_free(recv_msg); } - ret = kdbus_msg_recv(c, &recv_msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(recv_msg->src_id == b->id); + ASSERT_ZERO(kdbus_msg_recv(c, &recv_msg, NULL)); + ASSERT_RETURN(recv_msg->src_id,==,b->id); kdbus_msg_free(recv_msg); - ret = kdbus_msg_recv(c, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(c, NULL, NULL)); free(msg); free(payload); @@ -622,47 +593,35 @@ int kdbus_test_pool_quota(struct kdbus_test_env *env) return 0; } -int kdbus_test_message_quota(struct kdbus_test_env *env) +wur int kdbus_test_message_quota(struct kdbus_test_env *env) { struct kdbus_conn *a, *b; uint64_t cookie = 0; - int ret; - int i; + unsigned i; - ret = kdbus_test_activator_quota(env); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_test_notify_kernel_quota(env)); - ret = kdbus_test_notify_kernel_quota(env); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_test_pool_quota(env)); - ret = kdbus_test_pool_quota(env); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_test_expected_reply_timeouts_or_quota(env)); - ret = kdbus_test_expected_reply_quota(env); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_test_expected_reply_quota(env)); a = kdbus_hello(env->buspath, 0, NULL, 0); b = kdbus_hello(env->buspath, 0, NULL, 0); - ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS); - ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS); + ASSERT_RETURN((typeof(kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS)))KDBUS_CONN_MAX_MSGS,==,kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS)); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id, 0, NULL); - ASSERT_RETURN(ret == -ENOBUFS); + ASSERT_RETURN(-ENOBUFS,==,kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id)); - for (i = 0; i < KDBUS_CONN_MAX_MSGS; ++i) { - ret = kdbus_msg_recv(a, NULL, NULL); - ASSERT_RETURN(ret == 0); - } + for (i = 0; i < KDBUS_CONN_MAX_MSGS; ++i) + ASSERT_ZERO(kdbus_msg_recv(a, NULL, NULL)); - ret = kdbus_msg_recv(a, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(a, NULL, NULL)); - ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1); - ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS); + ASSERT_RETURN((typeof(kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1)))KDBUS_CONN_MAX_MSGS,==,kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1)); - ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id, 0, NULL); - ASSERT_RETURN(ret == -ENOBUFS); + ASSERT_RETURN(-ENOBUFS,==,kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id)); kdbus_conn_free(a); kdbus_conn_free(b); @@ -670,7 +629,7 @@ int kdbus_test_message_quota(struct kdbus_test_env *env) return TEST_OK; } -int kdbus_test_memory_access(struct kdbus_test_env *env) +wur int kdbus_test_memory_access(struct kdbus_test_env *env) { struct kdbus_conn *a, *b; struct kdbus_cmd_send cmd = {}; @@ -680,7 +639,6 @@ int kdbus_test_memory_access(struct kdbus_test_env *env) char line[256]; uint64_t size; FILE *f; - int ret; /* * Search in /proc/kallsyms for the address of a kernel symbol that @@ -712,15 +670,14 @@ int kdbus_test_memory_access(struct kdbus_test_env *env) if (!test_addr) return TEST_SKIP; - a = kdbus_hello(env->buspath, 0, NULL, 0); - b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(a && b); + ASSERT_NONZERO(a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(b = kdbus_hello(env->buspath, 0, NULL, 0)); size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); msg = alloca(size); - ASSERT_RETURN_VAL(msg, -ENOMEM); + ASSERT_RETURN_VAL(msg,!=,NULL, -ENOMEM); memset(msg, 0, size); msg->size = size; @@ -738,8 +695,7 @@ int kdbus_test_memory_access(struct kdbus_test_env *env) cmd.size = sizeof(cmd); cmd.msg_address = (uintptr_t)msg; - ret = kdbus_cmd_send(a->fd, &cmd); - ASSERT_RETURN(ret == -EFAULT); + ASSERT_RETURN(-EFAULT,==,kdbus_cmd_send(a->fd, &cmd)); kdbus_conn_free(b); kdbus_conn_free(a); diff --git a/tools/testing/selftests/kdbus/test-metadata-ns.c b/tools/testing/selftests/kdbus/test-metadata-ns.c index 395a3fa..6b02ba7 100644 --- a/tools/testing/selftests/kdbus/test-metadata-ns.c +++ b/tools/testing/selftests/kdbus/test-metadata-ns.c @@ -55,35 +55,25 @@ static struct kdbus_item *kdbus_get_item(struct kdbus_msg *msg, return NULL; } -static int kdbus_match_kdbus_creds(struct kdbus_msg *msg, +static wur int kdbus_match_kdbus_creds(struct kdbus_msg *msg, const struct kdbus_creds *expected_creds) { struct kdbus_item *item; - - item = kdbus_get_item(msg, KDBUS_ITEM_CREDS); - ASSERT_RETURN(item); - - ASSERT_RETURN(memcmp(&item->creds, expected_creds, - sizeof(struct kdbus_creds)) == 0); - + ASSERT_NONZERO(item = kdbus_get_item(msg, KDBUS_ITEM_CREDS)); + ASSERT_ZERO(memcmp(&item->creds, expected_creds, sizeof(struct kdbus_creds))); return 0; } -static int kdbus_match_kdbus_pids(struct kdbus_msg *msg, +static wur int kdbus_match_kdbus_pids(struct kdbus_msg *msg, const struct kdbus_pids *expected_pids) { struct kdbus_item *item; - - item = kdbus_get_item(msg, KDBUS_ITEM_PIDS); - ASSERT_RETURN(item); - - ASSERT_RETURN(memcmp(&item->pids, expected_pids, - sizeof(struct kdbus_pids)) == 0); - + ASSERT_NONZERO(item = kdbus_get_item(msg, KDBUS_ITEM_PIDS)); + ASSERT_ZERO(memcmp(&item->pids, expected_pids, sizeof(struct kdbus_pids))); return 0; } -static int __kdbus_clone_userns_test(const char *bus, +static wur int __kdbus_clone_userns_test(const char *bus, struct kdbus_conn *conn, uint64_t grandpa_pid, int signal_fd) @@ -100,23 +90,18 @@ static int __kdbus_clone_userns_test(const char *bus, .ppid = grandpa_pid, }; - ret = drop_privileges(UNPRIV_UID, UNPRIV_GID); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(drop_privileges(UNPRIV_UID, UNPRIV_GID)); - unpriv_conn = kdbus_hello(bus, 0, NULL, 0); - ASSERT_EXIT(unpriv_conn); + ASSERT_EXIT_NONZERO(unpriv_conn = kdbus_hello(bus, 0, NULL, 0)); - ret = kdbus_add_match_empty(unpriv_conn); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_add_match_empty(unpriv_conn)); /* * ping privileged connection from this new unprivileged * one */ - ret = kdbus_msg_send(unpriv_conn, NULL, cookie, 0, 0, - 0, conn->id, 0, NULL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv_conn, NULL, cookie, 0, 0, 0, conn->id)); /* * Since we just dropped privileges, the dumpable flag @@ -130,8 +115,7 @@ static int __kdbus_clone_userns_test(const char *bus, * Using this we will be able write to /proc/$clone_child/uid_map * as uid 65534 and map the uid 65534 to 0 inside the user namespace. */ - ret = prctl(PR_SET_DUMPABLE, SUID_DUMP_USER); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(prctl(PR_SET_DUMPABLE, SUID_DUMP_USER)); /* Make child privileged in its new userns and run tests */ @@ -143,20 +127,16 @@ static int __kdbus_clone_userns_test(const char *bus, struct kdbus_conn *userns_conn; /* ping connection from the new user namespace */ - userns_conn = kdbus_hello(bus, 0, NULL, 0); - ASSERT_EXIT(userns_conn); + ASSERT_EXIT_NONZERO(userns_conn = kdbus_hello(bus, 0, NULL, 0)); - ret = kdbus_add_match_empty(userns_conn); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_add_match_empty(userns_conn)); cookie++; - ret = kdbus_msg_send(userns_conn, NULL, cookie, - 0, 0, 0, conn->id, 0, NULL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_msg_send(userns_conn, NULL, cookie, 0, 0, 0, conn->id)); /* Parent did send */ - ret = eventfd_read(signal_fd, &event_status); - ASSERT_RETURN(ret >= 0 && event_status == 1); + ASSERT_RETURN(0,<=,eventfd_read(signal_fd, &event_status)); + ASSERT_RETURN(event_status,==,(eventfd_t)1); /* * Receive from privileged connection @@ -164,24 +144,19 @@ static int __kdbus_clone_userns_test(const char *bus, kdbus_printf("Privileged → unprivileged/privileged " "in its userns " "(different userns and pidns):\n"); - ret = kdbus_msg_recv_poll(userns_conn, 300, &msg, NULL); - ASSERT_EXIT(ret == 0); - ASSERT_EXIT(msg->dst_id == userns_conn->id); + ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(userns_conn, 300, &msg, NULL)); + ASSERT_EXIT(msg->dst_id,==,userns_conn->id); - /* Different namespaces no CAPS */ - item = kdbus_get_item(msg, KDBUS_ITEM_CAPS); - ASSERT_EXIT(item == NULL); + ASSERT_EXIT_NONZERO(item = kdbus_get_item(msg, KDBUS_ITEM_CAPS)); /* uid/gid not mapped, so we have unpriv cached creds */ - ret = kdbus_match_kdbus_creds(msg, &unmapped_creds); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_match_kdbus_creds(msg, &unmapped_creds)); /* * Diffent pid namepsaces. This is the child pidns * so it should not see its parent kdbus_pids */ - ret = kdbus_match_kdbus_pids(msg, &unmapped_pids); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_match_kdbus_pids(msg, &unmapped_pids)); kdbus_msg_free(msg); @@ -192,24 +167,19 @@ static int __kdbus_clone_userns_test(const char *bus, kdbus_printf("Privileged → unprivileged/privileged " "in its userns " "(different userns and pidns):\n"); - ret = kdbus_msg_recv_poll(userns_conn, 300, &msg, NULL); - ASSERT_EXIT(ret == 0); - ASSERT_EXIT(msg->dst_id == KDBUS_DST_ID_BROADCAST); + ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(userns_conn, 300, &msg, NULL)); + ASSERT_EXIT(msg->dst_id,==,KDBUS_DST_ID_BROADCAST); - /* Different namespaces no CAPS */ - item = kdbus_get_item(msg, KDBUS_ITEM_CAPS); - ASSERT_EXIT(item == NULL); + ASSERT_EXIT_NONZERO(item = kdbus_get_item(msg, KDBUS_ITEM_CAPS)); /* uid/gid not mapped, so we have unpriv cached creds */ - ret = kdbus_match_kdbus_creds(msg, &unmapped_creds); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_match_kdbus_creds(msg, &unmapped_creds)); /* * Diffent pid namepsaces. This is the child pidns * so it should not see its parent kdbus_pids */ - ret = kdbus_match_kdbus_pids(msg, &unmapped_pids); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_match_kdbus_pids(msg, &unmapped_pids)); kdbus_msg_free(msg); @@ -217,8 +187,7 @@ static int __kdbus_clone_userns_test(const char *bus, }), ({ /* Parent setup map child uid/gid */ - ret = userns_map_uid_gid(pid, "0 65534 1", "0 65534 1"); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(userns_map_uid_gid(pid, "0 65534 1", "0 65534 1")); }), ({ 0; })); /* Unprivileged was not able to create user namespace */ @@ -231,25 +200,21 @@ static int __kdbus_clone_userns_test(const char *bus, goto out; } - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(ret); /* * Receive from privileged connection */ kdbus_printf("\nPrivileged → unprivileged (same namespaces):\n"); - ret = kdbus_msg_recv_poll(unpriv_conn, 300, &msg, NULL); - - ASSERT_EXIT(ret == 0); - ASSERT_EXIT(msg->dst_id == unpriv_conn->id); + ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(unpriv_conn, 300, &msg, NULL)); + ASSERT_EXIT(msg->dst_id,==,unpriv_conn->id); /* will get the privileged creds */ - ret = kdbus_match_kdbus_creds(msg, &privileged_creds); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_match_kdbus_creds(msg, &privileged_creds)); /* Same pidns so will get the kdbus_pids */ - ret = kdbus_match_kdbus_pids(msg, &parent_pids); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_match_kdbus_pids(msg, &parent_pids)); kdbus_msg_free(msg); @@ -258,17 +223,13 @@ static int __kdbus_clone_userns_test(const char *bus, * Receive broadcast from privileged connection */ kdbus_printf("\nPrivileged → unprivileged (same namespaces):\n"); - ret = kdbus_msg_recv_poll(unpriv_conn, 300, &msg, NULL); - - ASSERT_EXIT(ret == 0); - ASSERT_EXIT(msg->dst_id == KDBUS_DST_ID_BROADCAST); + ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(unpriv_conn, 300, &msg, NULL)); + ASSERT_EXIT(msg->dst_id,==,KDBUS_DST_ID_BROADCAST); /* will get the privileged creds */ - ret = kdbus_match_kdbus_creds(msg, &privileged_creds); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_match_kdbus_creds(msg, &privileged_creds)); - ret = kdbus_match_kdbus_pids(msg, &parent_pids); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_match_kdbus_pids(msg, &parent_pids)); kdbus_msg_free(msg); @@ -278,43 +239,39 @@ out: return ret; } -static int kdbus_clone_userns_test(const char *bus, +static wur int kdbus_clone_userns_test(const char *bus, struct kdbus_conn *conn) { - int ret; - int status; - int efd = -1; + int ret, status, efd; pid_t pid, ppid; - uint64_t unpriv_conn_id = 0; - uint64_t userns_conn_id = 0; + uint64_t unpriv_conn_id, userns_conn_id; struct kdbus_msg *msg; const struct kdbus_item *item; struct kdbus_pids expected_pids; - struct kdbus_conn *monitor = NULL; + struct kdbus_conn *monitor; kdbus_printf("STARTING TEST 'metadata-ns'.\n"); - monitor = kdbus_hello(bus, KDBUS_HELLO_MONITOR, NULL, 0); - ASSERT_EXIT(monitor); + ASSERT_EXIT_NONZERO(monitor = kdbus_hello(bus, KDBUS_HELLO_MONITOR, NULL, 0)); /* * parent will signal to child that is in its * userns to read its queue */ efd = eventfd(0, EFD_CLOEXEC); - ASSERT_RETURN_VAL(efd >= 0, efd); + ASSERT_RETURN_VAL(efd,>=,0, efd); ppid = getppid(); pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, -errno); + ASSERT_RETURN_VAL(pid,>=,0, -errno); if (pid == 0) { ret = prctl(PR_SET_PDEATHSIG, SIGKILL); - ASSERT_EXIT_VAL(ret == 0, -errno); + ASSERT_EXIT_VAL(ret,==,0, -errno); ret = __kdbus_clone_userns_test(bus, conn, ppid, efd); - _exit(ret); + exit(ret); } @@ -324,14 +281,12 @@ static int kdbus_clone_userns_test(const char *bus, * Receive from the unprivileged child */ kdbus_printf("\nUnprivileged → privileged (same namespaces):\n"); - ret = kdbus_msg_recv_poll(conn, 300, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(conn, 300, &msg, NULL)); unpriv_conn_id = msg->src_id; /* Unprivileged user */ - ret = kdbus_match_kdbus_creds(msg, &unmapped_creds); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_match_kdbus_creds(msg, &unmapped_creds)); /* Set the expected creds_pids */ expected_pids = (struct kdbus_pids) { @@ -339,8 +294,7 @@ static int kdbus_clone_userns_test(const char *bus, .tid = pid, .ppid = getpid(), }; - ret = kdbus_match_kdbus_pids(msg, &expected_pids); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_match_kdbus_pids(msg, &expected_pids)); kdbus_msg_free(msg); @@ -357,36 +311,31 @@ static int kdbus_clone_userns_test(const char *bus, /* perhaps unprivileged userns is not allowed */ goto wait; - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(ret); userns_conn_id = msg->src_id; - /* We do not share the userns, os no KDBUS_ITEM_CAPS */ - item = kdbus_get_item(msg, KDBUS_ITEM_CAPS); - ASSERT_RETURN(item == NULL); + ASSERT_NONZERO(item = kdbus_get_item(msg, KDBUS_ITEM_CAPS)); /* * Compare received items, creds must be translated into * the receiver user namespace, so the user is unprivileged */ - ret = kdbus_match_kdbus_creds(msg, &unmapped_creds); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_match_kdbus_creds(msg, &unmapped_creds)); /* * We should have the kdbus_pids since we are the parent * pidns */ - item = kdbus_get_item(msg, KDBUS_ITEM_PIDS); - ASSERT_RETURN(item); + ASSERT_NONZERO(item = kdbus_get_item(msg, KDBUS_ITEM_PIDS)); - ASSERT_RETURN(memcmp(&item->pids, &unmapped_pids, - sizeof(struct kdbus_pids)) != 0); + ASSERT_NONZERO(memcmp(&item->pids, &unmapped_pids, sizeof(struct kdbus_pids))); /* * Parent pid of the unprivileged/privileged in its userns * is the unprivileged child pid that was forked here. */ - ASSERT_RETURN((uint64_t)pid == item->pids.ppid); + ASSERT_RETURN((uint64_t)pid,==,item->pids.ppid); kdbus_msg_free(msg); @@ -396,36 +345,29 @@ static int kdbus_clone_userns_test(const char *bus, /* * Sending to unprivileged connections a unicast */ - ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, - 0, unpriv_conn_id, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, unpriv_conn_id)); /* signal to child that is in its userns */ - ret = eventfd_write(efd, 1); - ASSERT_EXIT(ret == 0); + ASSERT_ZERO(eventfd_write(efd, 1)); /* * Sending to unprivileged/privilged in its userns * connections a unicast */ - ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, - 0, userns_conn_id, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, userns_conn_id)); /* * Sending to unprivileged connections a broadcast */ - ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, - 0, KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); wait: ret = waitpid(pid, &status, 0); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); - ASSERT_RETURN(WIFEXITED(status)) - ASSERT_RETURN(!WEXITSTATUS(status)); + ASSERT_NONZERO(WIFEXITED(status)); + ASSERT_ZERO(WEXITSTATUS(status)); /* Dump monitor queue */ kdbus_printf("\n\nMonitor queue:\n"); @@ -439,24 +381,22 @@ wait: * Parent pidns should see all the * pids */ - item = kdbus_get_item(msg, KDBUS_ITEM_PIDS); - ASSERT_RETURN(item); - - ASSERT_RETURN(item->pids.pid != 0 && - item->pids.tid != 0 && - item->pids.ppid != 0); + ASSERT_NONZERO(item = kdbus_get_item(msg, KDBUS_ITEM_PIDS)); + ASSERT_NONZERO(item->pids.pid); + ASSERT_NONZERO(item->pids.tid != 0); + ASSERT_NONZERO(item->pids.ppid != 0); } kdbus_msg_free(msg); } kdbus_conn_free(monitor); - close(efd); + CLOSE(efd); return 0; } -int kdbus_test_metadata_ns(struct kdbus_test_env *env) +wur int kdbus_test_metadata_ns(struct kdbus_test_env *env) { int ret; struct kdbus_conn *holder, *conn; @@ -476,31 +416,104 @@ int kdbus_test_metadata_ns(struct kdbus_test_env *env) return TEST_SKIP; ret = test_is_capable(CAP_SETUID, CAP_SETGID, CAP_SYS_ADMIN, -1); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); /* no enough privileges, SKIP test */ if (!ret) return TEST_SKIP; - holder = kdbus_hello_registrar(env->buspath, "com.example.metadata", - &policy_access, 1, - KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(holder); + ASSERT_NONZERO(holder = kdbus_hello_registrar(env->buspath, "com.example.metadata", &policy_access, 1, KDBUS_HELLO_POLICY_HOLDER)); - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_add_match_empty(conn); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn)); - ret = kdbus_name_acquire(conn, "com.example.metadata", NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_ZERO(kdbus_name_acquire(conn, "com.example.metadata", NULL)); - ret = kdbus_clone_userns_test(env->buspath, conn); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_clone_userns_test(env->buspath, conn)); kdbus_conn_free(holder); kdbus_conn_free(conn); return TEST_OK; } + +#define TEST_METADATA_DECL\ + int attach_flags_recv = _KDBUS_ATTACH_ALL; +#define TEST_METADATA_DECL_INLOOP\ + struct kdbus_item const *item;\ + bool have_desc=false, have_name=false;\ + if (attach_flags_recv & KDBUS_ATTACH_AUDIT) /* audit not generally supported - no reason to prolong the test by including it */\ + attach_flags_recv &= ~KDBUS_ATTACH_AUDIT; +#define TEST_METADATA(STRUCT) do {\ + KDBUS_ITEM_FOREACH(item, (STRUCT), items) {\ + if (KDBUS_ITEM_OWNED_NAME == item->type) {\ + ASSERT_ZERO(have_name);\ + have_name = true;\ + } else if (KDBUS_ITEM_CONN_DESCRIPTION == item->type) {\ + ASSERT_ZERO(have_desc);\ + have_desc = true;\ + }\ + }\ + if (attach_flags_recv & KDBUS_ATTACH_NAMES)\ + ASSERT_NONZERO(have_name);\ + else\ + ASSERT_ZERO(have_name);\ + if (attach_flags_recv & KDBUS_ATTACH_CONN_DESCRIPTION)\ + ASSERT_NONZERO(have_desc);\ + else\ + ASSERT_ZERO(have_desc);\ +} while (0) + +wur int kdbus_test_metadata(struct kdbus_test_env *env) +{ + struct kdbus_conn *conn; + struct kdbus_msg *msg; + uint64_t cookie = 0x1234abcd5678eeff; + + TEST_METADATA_DECL; + + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_ZERO(kdbus_name_acquire(conn, "dummy.name.yeah", NULL)); + + do { + TEST_METADATA_DECL_INLOOP; + + ASSERT_ZERO(kdbus_conn_update_attach_flags(env->conn, _KDBUS_ATTACH_ALL, attach_flags_recv)); + ASSERT_ZERO(kdbus_msg_send(conn, NULL, ++cookie, 0, 0, 0, env->conn->id)); + ASSERT_ZERO(kdbus_msg_recv(env->conn, &msg, NULL)); + + TEST_METADATA(msg); + + kdbus_msg_free(msg); + ASSERT_ZERO(kdbus_free(env->conn, (uintptr_t)msg - (uintptr_t)env->conn->buf)); + } while (--attach_flags_recv >= 0); + + kdbus_conn_free(conn); + + return TEST_OK; +} + +wur int kdbus_test_metadata_conn_info(struct kdbus_test_env *env) +{ + TEST_METADATA_DECL; + + ASSERT_ZERO(kdbus_name_acquire(env->conn, "dummy.name.yeah", NULL)); + + do { + struct kdbus_info *info; + uint64_t offset; + + TEST_METADATA_DECL_INLOOP; + + ASSERT_ZERO(kdbus_conn_info(env->conn, env->conn->id, NULL, attach_flags_recv, &offset)); + info = (struct kdbus_info *)(env->conn->buf + offset); + ASSERT_RETURN(info->id,==,env->conn->id); + + TEST_METADATA(info); + + ASSERT_ZERO(kdbus_free(env->conn, (uintptr_t)info - (uintptr_t)env->conn->buf)); + } while (--attach_flags_recv >= 0); + + return TEST_OK; +} diff --git a/tools/testing/selftests/kdbus/test-monitor.c b/tools/testing/selftests/kdbus/test-monitor.c index ae87d87..a5918e5 100644 --- a/tools/testing/selftests/kdbus/test-monitor.c +++ b/tools/testing/selftests/kdbus/test-monitor.c @@ -22,7 +22,7 @@ #include "kdbus-enum.h" #include "kdbus-test.h" -int kdbus_test_monitor(struct kdbus_test_env *env) +wur int kdbus_test_monitor(struct kdbus_test_env *env) { struct kdbus_conn *monitor, *conn; unsigned int cookie = 0xdeadbeef; @@ -30,148 +30,125 @@ int kdbus_test_monitor(struct kdbus_test_env *env) uint64_t offset = 0; int ret; - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* add matches to make sure the monitor do not trigger an item add or * remove on connect and disconnect, respectively. */ - ret = kdbus_add_match_id(conn, 0x1, KDBUS_ITEM_ID_ADD, - KDBUS_MATCH_ID_ANY); - ASSERT_RETURN(ret == 0); - - ret = kdbus_add_match_id(conn, 0x2, KDBUS_ITEM_ID_REMOVE, - KDBUS_MATCH_ID_ANY); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_id(conn, 0x1, KDBUS_ITEM_ID_ADD, KDBUS_MATCH_ID_ANY)); + ASSERT_ZERO(kdbus_add_match_id(conn, 0x2, KDBUS_ITEM_ID_REMOVE, KDBUS_MATCH_ID_ANY)); /* register a monitor */ - monitor = kdbus_hello(env->buspath, KDBUS_HELLO_MONITOR, NULL, 0); - ASSERT_RETURN(monitor); + ASSERT_NONZERO(monitor = kdbus_hello(env->buspath, KDBUS_HELLO_MONITOR, NULL, 0)); /* make sure we did not receive a monitor connect notification */ - ret = kdbus_msg_recv(conn, &msg, &offset); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn, &msg, &offset)); /* check that a monitor cannot acquire a name */ - ret = kdbus_name_acquire(monitor, "foo.bar.baz", NULL); - ASSERT_RETURN(ret == -EOPNOTSUPP); + ASSERT_RETURN(-EOPNOTSUPP,==,kdbus_name_acquire(monitor, "foo.bar.baz", NULL)); - ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, conn->id, - 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, conn->id)); /* the recipient should have gotten the message */ - ret = kdbus_msg_recv(conn, &msg, &offset); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv(conn, &msg, &offset)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); - kdbus_free(conn, offset); + ASSERT_ZERO(kdbus_free(conn, offset)); /* and so should the monitor */ - ret = kdbus_msg_recv(monitor, &msg, &offset); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv(monitor, &msg, &offset)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); - kdbus_free(monitor, offset); + ASSERT_ZERO(kdbus_free(monitor, offset)); + + /* make sure there are no pending messages */ + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn, &msg, &offset)); - /* Installing matches for monitors must fais must fail */ - ret = kdbus_add_match_empty(monitor); - ASSERT_RETURN(ret == -EOPNOTSUPP); + /* Installing matches for monitors must fail */ + ASSERT_RETURN(-EOPNOTSUPP,==,kdbus_add_match_empty(monitor)); cookie++; - ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); + + /* make sure there are no pending messages */ + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn, &msg, &offset)); /* The monitor should get the message. */ - ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv_poll(monitor, 100, &msg, &offset)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); - kdbus_free(monitor, offset); + ASSERT_ZERO(kdbus_free(monitor, offset)); /* * Since we are the only monitor, update the attach flags - * and tell we are not interessted in attach flags recv + * and tell we are not interested in attach flags recv */ - ret = kdbus_conn_update_attach_flags(monitor, - _KDBUS_ATTACH_ALL, - 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_attach_flags(monitor, _KDBUS_ATTACH_ALL, 0)); cookie++; - ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); - ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + /* make sure there are no pending messages */ + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn, &msg, &offset)); - ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(monitor, 100, &msg, &offset)); + ASSERT_RETURN(msg->cookie,==,cookie); + + ASSERT_ZERO(kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP)); kdbus_msg_free(msg); - kdbus_free(monitor, offset); + ASSERT_ZERO(kdbus_free(monitor, offset)); /* * Now we are interested in KDBUS_ITEM_TIMESTAMP and * KDBUS_ITEM_CREDS */ - ret = kdbus_conn_update_attach_flags(monitor, - _KDBUS_ATTACH_ALL, - KDBUS_ATTACH_TIMESTAMP | - KDBUS_ATTACH_CREDS); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_attach_flags(monitor, _KDBUS_ATTACH_ALL, KDBUS_ATTACH_TIMESTAMP | KDBUS_ATTACH_CREDS)); cookie++; - ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); + + /* make sure there are no pending messages */ + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn, &msg, &offset)); - ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv_poll(monitor, 100, &msg, &offset)); + ASSERT_RETURN(msg->cookie,==,cookie); - ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP); - ASSERT_RETURN(ret == 1); + ASSERT_RETURN(1,==,kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP)); - ret = kdbus_item_in_message(msg, KDBUS_ITEM_CREDS); - ASSERT_RETURN(ret == 1); + ASSERT_RETURN(1,==,kdbus_item_in_message(msg, KDBUS_ITEM_CREDS)); /* the KDBUS_ITEM_PID_COMM was not requested */ - ret = kdbus_item_in_message(msg, KDBUS_ITEM_PID_COMM); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_item_in_message(msg, KDBUS_ITEM_PID_COMM)); kdbus_msg_free(msg); - kdbus_free(monitor, offset); + ASSERT_ZERO(kdbus_free(monitor, offset)); + + /* make sure there are no pending messages */ + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn, &msg, &offset)); kdbus_conn_free(monitor); /* make sure we did not receive a monitor disconnect notification */ - ret = kdbus_msg_recv(conn, &msg, &offset); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(conn, &msg, &offset)); kdbus_conn_free(conn); /* Make sure that monitor as unprivileged is not allowed */ ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); - if (ret && all_uids_gids_are_mapped()) { - ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({ - monitor = kdbus_hello(env->buspath, - KDBUS_HELLO_MONITOR, - NULL, 0); - ASSERT_EXIT(!monitor && errno == EPERM); + if (ret && all_uids_gids_are_mapped()) + RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({ + monitor = kdbus_hello(env->buspath, KDBUS_HELLO_MONITOR, NULL, 0); + ASSERT_EXIT(errno,==,EPERM); + ASSERT_EXIT_ZERO(monitor); - _exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); }), - ({ 0; })); - ASSERT_RETURN(ret == 0); - } + ({})); return TEST_OK; } diff --git a/tools/testing/selftests/kdbus/test-names.c b/tools/testing/selftests/kdbus/test-names.c index 66ebb47..aedbac7 100644 --- a/tools/testing/selftests/kdbus/test-names.c +++ b/tools/testing/selftests/kdbus/test-names.c @@ -17,46 +17,72 @@ #include "kdbus-enum.h" #include "kdbus-test.h" -static int conn_is_name_owner(const struct kdbus_conn *conn, - const char *needle) +struct test_name { + const char *name; + __u64 owner_id; + __u64 flags; +}; + +static wur bool conn_test_names(const struct kdbus_conn *conn, + const struct test_name *tests, + unsigned int n_tests) { - struct kdbus_cmd_list cmd_list = { .size = sizeof(cmd_list) }; + struct kdbus_cmd_list cmd_list = {}; struct kdbus_info *name, *list; - bool found = false; - int ret; + unsigned int i; - cmd_list.flags = KDBUS_LIST_NAMES; + cmd_list.size = sizeof(cmd_list); + cmd_list.flags = KDBUS_LIST_NAMES | + KDBUS_LIST_ACTIVATORS | + KDBUS_LIST_QUEUED; - ret = kdbus_cmd_list(conn->fd, &cmd_list); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_cmd_list(conn->fd, &cmd_list)); list = (struct kdbus_info *)(conn->buf + cmd_list.offset); - KDBUS_FOREACH(name, list, cmd_list.list_size) { - struct kdbus_item *item; - const char *n = NULL; - - KDBUS_ITEM_FOREACH(item, name, items) - if (item->type == KDBUS_ITEM_OWNED_NAME) - n = item->name.name; - - if (name->id == conn->id && - n && strcmp(needle, n) == 0) { - found = true; - break; + + for (i = 0; i < n_tests; i++) { + const struct test_name *t = tests + i; + bool found = false; + + KDBUS_FOREACH(name, list, cmd_list.list_size) { + struct kdbus_item *item; + + KDBUS_ITEM_FOREACH(item, name, items) { + if (item->type != KDBUS_ITEM_OWNED_NAME || + strcmp(item->name.name, t->name) != 0) + continue; + + if (t->owner_id == name->id && + t->flags == item->name.flags) { + found = true; + break; + } + } } + + if (!found) + return false; } - ret = kdbus_free(conn, cmd_list.offset); - ASSERT_RETURN(ret == 0); + return true; +} - return found ? 0 : -1; +static wur bool conn_is_name_primary_owner(const struct kdbus_conn *conn, + const char *needle) +{ + struct test_name t = { + .name = needle, + .owner_id = conn->id, + .flags = KDBUS_NAME_PRIMARY, + }; + + return conn_test_names(conn, &t, 1); } -int kdbus_test_name_basic(struct kdbus_test_env *env) +wur int kdbus_test_name_basic(struct kdbus_test_env *env) { struct kdbus_conn *conn; char *name, *dot_name, *invalid_name, *wildcard_name; - int ret; name = "foo.bla.blaz"; dot_name = ".bla.blaz"; @@ -64,129 +90,145 @@ int kdbus_test_name_basic(struct kdbus_test_env *env) wildcard_name = "foo.bla.bl.*"; /* create a 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* acquire name "foo.bar.xxx" name */ - ret = kdbus_name_acquire(conn, "foo.bar.xxx", NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn, "foo.bar.xxx", NULL)); /* Name is not valid, must fail */ - ret = kdbus_name_acquire(env->conn, dot_name, NULL); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_name_acquire(env->conn, dot_name, NULL)); - ret = kdbus_name_acquire(env->conn, invalid_name, NULL); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_name_acquire(env->conn, invalid_name, NULL)); - ret = kdbus_name_acquire(env->conn, wildcard_name, NULL); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_name_acquire(env->conn, wildcard_name, NULL)); /* check that we can acquire a name */ - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, NULL)); - ret = conn_is_name_owner(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_RETURN(true,==,conn_is_name_primary_owner(env->conn, name)); /* ... and release it again */ - ret = kdbus_name_release(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_release(env->conn, name)); - ret = conn_is_name_owner(env->conn, name); - ASSERT_RETURN(ret != 0); + ASSERT_RETURN(false,==,conn_is_name_primary_owner(env->conn, name)); /* check that we can't release it again */ - ret = kdbus_name_release(env->conn, name); - ASSERT_RETURN(ret == -ESRCH); + ASSERT_RETURN(-ESRCH,==,kdbus_name_release(env->conn, name)); /* check that we can't release a name that we don't own */ - ret = kdbus_name_release(env->conn, "foo.bar.xxx"); - ASSERT_RETURN(ret == -EADDRINUSE); + ASSERT_RETURN(-EADDRINUSE,==,kdbus_name_release(env->conn, "foo.bar.xxx")); /* Name is not valid, must fail */ - ret = kdbus_name_release(env->conn, dot_name); - ASSERT_RETURN(ret == -ESRCH); + ASSERT_RETURN(-ESRCH,==,kdbus_name_release(env->conn, dot_name)); - ret = kdbus_name_release(env->conn, invalid_name); - ASSERT_RETURN(ret == -ESRCH); + ASSERT_RETURN(-ESRCH,==,kdbus_name_release(env->conn, invalid_name)); - ret = kdbus_name_release(env->conn, wildcard_name); - ASSERT_RETURN(ret == -ESRCH); + ASSERT_RETURN(-ESRCH,==,kdbus_name_release(env->conn, wildcard_name)); kdbus_conn_free(conn); return TEST_OK; } -int kdbus_test_name_conflict(struct kdbus_test_env *env) +wur int kdbus_test_name_conflict(struct kdbus_test_env *env) { struct kdbus_conn *conn; char *name; - int ret; name = "foo.bla.blaz"; /* create a 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* allow the new connection to own the same name */ /* acquire name from the 1st connection */ - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == 0); - - ret = conn_is_name_owner(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, NULL)); - /* check that we can't acquire it again from the 1st connection */ - ret = kdbus_name_acquire(env->conn, name, NULL); - ASSERT_RETURN(ret == -EALREADY); + ASSERT_RETURN(true,==,conn_is_name_primary_owner(env->conn, name)); /* check that we also can't acquire it again from the 2nd connection */ - ret = kdbus_name_acquire(conn, name, NULL); - ASSERT_RETURN(ret == -EEXIST); + ASSERT_RETURN(-EEXIST,==,kdbus_name_acquire(conn, name, NULL)); kdbus_conn_free(conn); return TEST_OK; } -int kdbus_test_name_queue(struct kdbus_test_env *env) +wur int kdbus_test_name_queue(struct kdbus_test_env *env) { struct kdbus_conn *conn; + struct test_name t[2]; const char *name; uint64_t flags; - int ret; name = "foo.bla.blaz"; - flags = KDBUS_NAME_ALLOW_REPLACEMENT; + flags = 0; /* create a 2nd connection */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn != NULL); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* allow the new connection to own the same name */ /* acquire name from the 1st connection */ - ret = kdbus_name_acquire(env->conn, name, &flags); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, &flags)); - ret = conn_is_name_owner(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_RETURN(true,==,conn_is_name_primary_owner(env->conn, name)); /* queue the 2nd connection as waiting owner */ flags = KDBUS_NAME_QUEUE; - ret = kdbus_name_acquire(conn, name, &flags); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(flags & KDBUS_NAME_IN_QUEUE); + ASSERT_ZERO(kdbus_name_acquire(conn, name, &flags)); + ASSERT_NONZERO(flags & KDBUS_NAME_IN_QUEUE); + + t[0].name = name; + t[0].owner_id = env->conn->id; + t[0].flags = KDBUS_NAME_PRIMARY; + t[1].name = name; + t[1].owner_id = conn->id; + t[1].flags = KDBUS_NAME_QUEUE | KDBUS_NAME_IN_QUEUE; + ASSERT_RETURN(true,==,conn_test_names(conn, t, 2)); /* release name from 1st connection */ - ret = kdbus_name_release(env->conn, name); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_release(env->conn, name)); /* now the name should be owned by the 2nd connection */ - ret = conn_is_name_owner(conn, name); - ASSERT_RETURN(ret == 0); + t[0].name = name; + t[0].owner_id = conn->id; + t[0].flags = KDBUS_NAME_PRIMARY | KDBUS_NAME_QUEUE; + ASSERT_RETURN(true,==,conn_test_names(conn, t, 1)); + + kdbus_conn_free(conn); + + return TEST_OK; +} + +wur int kdbus_test_name_takeover(struct kdbus_test_env *env) +{ + struct kdbus_conn *conn; + struct test_name t; + const char *name; + uint64_t flags; + + name = "foo.bla.blaz"; + + flags = KDBUS_NAME_ALLOW_REPLACEMENT; + + /* create a 2nd connection */ + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); + + /* acquire name for 1st connection */ + ASSERT_ZERO(kdbus_name_acquire(env->conn, name, &flags)); + + t.name = name; + t.owner_id = env->conn->id; + t.flags = KDBUS_NAME_ALLOW_REPLACEMENT | KDBUS_NAME_PRIMARY; + ASSERT_RETURN(true,==,conn_test_names(conn, &t, 1)); + + /* now steal name with 2nd connection */ + flags = KDBUS_NAME_REPLACE_EXISTING; + ASSERT_ZERO(kdbus_name_acquire(conn, name, &flags)); + ASSERT_NONZERO(flags & KDBUS_NAME_ACQUIRED); + + ASSERT_RETURN(true,==,conn_is_name_primary_owner(conn, name)); kdbus_conn_free(conn); diff --git a/tools/testing/selftests/kdbus/test-policy-ns.c b/tools/testing/selftests/kdbus/test-policy-ns.c index 2d70ee4..0a630b7 100644 --- a/tools/testing/selftests/kdbus/test-policy-ns.c +++ b/tools/testing/selftests/kdbus/test-policy-ns.c @@ -57,36 +57,34 @@ */ static struct kdbus_conn **conn_db; -static void *kdbus_recv_echo(void *ptr) +static wur void *kdbus_recv_echo(void *ptr) { int ret; struct kdbus_conn *conn = ptr; - ret = kdbus_msg_recv_poll(conn, 200, NULL, NULL); + ret = kdbus_msg_recv_poll(conn, 3009, NULL, NULL); return (void *)(long)ret; } /* Trigger kdbus_policy_set() */ -static int kdbus_set_policy_talk(struct kdbus_conn *conn, +static wur int kdbus_set_policy_talk(struct kdbus_conn *conn, const char *name, uid_t id, unsigned int type) { - int ret; struct kdbus_policy_access access = { .type = type, .id = id, .access = KDBUS_POLICY_TALK, }; - ret = kdbus_conn_update_policy(conn, name, &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn, name, &access, 1)); return TEST_OK; } /* return TEST_OK or TEST_ERR on failure */ -static int kdbus_register_same_activator(char *bus, const char *name, +static wur int kdbus_register_same_activator(char *bus, const char *name, struct kdbus_conn **c) { int ret; @@ -95,8 +93,7 @@ static int kdbus_register_same_activator(char *bus, const char *name, activator = kdbus_hello_activator(bus, name, NULL, 0); if (activator) { *c = activator; - fprintf(stderr, "--- error was able to register name twice '%s'.\n", - name); + print("--- error was able to register name twice '%s'.\n", name); return TEST_ERR; } @@ -109,7 +106,7 @@ static int kdbus_register_same_activator(char *bus, const char *name, } /* return TEST_OK or TEST_ERR on failure */ -static int kdbus_register_policy_holder(char *bus, const char *name, +static wur int kdbus_register_policy_holder(char *bus, const char *name, struct kdbus_conn **conn) { struct kdbus_conn *c; @@ -123,9 +120,7 @@ static int kdbus_register_policy_holder(char *bus, const char *name, access[1].access = KDBUS_POLICY_TALK; access[1].id = geteuid(); - c = kdbus_hello_registrar(bus, name, access, 2, - KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(c); + ASSERT_NONZERO(c = kdbus_hello_registrar(bus, name, access, 2, KDBUS_HELLO_POLICY_HOLDER)); *conn = c; @@ -139,7 +134,7 @@ static int kdbus_register_policy_holder(char *bus, const char *name, * * return 0 on success, negative errno on failure. */ -static int kdbus_recv_in_threads(const char *bus, const char *name, +static wur int kdbus_recv_in_threads(const char *bus, const char *name, struct kdbus_conn **conn_db) { int ret; @@ -180,7 +175,7 @@ static int kdbus_recv_in_threads(const char *bus, const char *name, break; ret = kdbus_msg_send(conn_db[i], name, cookie++, - 0, 0, 0, dst_id, 0, NULL); + 0, 0, 0, dst_id); if (ret < 0) { /* * Receivers are not reading their messages, @@ -219,7 +214,7 @@ static int kdbus_recv_in_threads(const char *bus, const char *name, * least have sent_packets set to KDBUS_CONN_MAX_MSGS_PER_USER */ if (pool_full) { - ASSERT_RETURN(lost_packets > 0); + ASSERT_NONZERO(lost_packets); /* * We should at least send KDBUS_CONN_MAX_MSGS_PER_USER @@ -227,7 +222,7 @@ static int kdbus_recv_in_threads(const char *bus, const char *name, * For every send operation we create a thread to * recv the packet, so we keep the queue clean */ - ASSERT_RETURN(sent_packets >= KDBUS_CONN_MAX_MSGS_PER_USER); + ASSERT_RETURN(sent_packets,>=,(unsigned)KDBUS_CONN_MAX_MSGS_PER_USER); /* * Set ret to zero since we only failed due to @@ -241,18 +236,14 @@ static int kdbus_recv_in_threads(const char *bus, const char *name, } /* Return: TEST_OK or TEST_ERR on failure */ -static int kdbus_normal_test(const char *bus, const char *name, +static wur int kdbus_normal_test(const char *bus, const char *name, struct kdbus_conn **conn_db) { - int ret; - - ret = kdbus_recv_in_threads(bus, name, conn_db); - ASSERT_RETURN(ret >= 0); - + ASSERT_RETURN(0,<=,kdbus_recv_in_threads(bus, name, conn_db)); return TEST_OK; } -static int kdbus_fork_test_by_id(const char *bus, +static wur int kdbus_fork_test_by_id(const char *bus, struct kdbus_conn **conn_db, int parent_status, int child_status) { @@ -263,42 +254,43 @@ static int kdbus_fork_test_by_id(const char *bus, uint64_t offset = 0; int status = 0; + bool parent_timedout; + bool child_timedout; + +#ifdef TIZEN + child_status = parent_status = 0; +#endif + /* * If the child_status is not EXIT_SUCCESS, then we expect * that sending from the child will fail, thus receiving * from parent must error with -ETIMEDOUT, and vice versa. */ - bool parent_timedout = !!child_status; - bool child_timedout = !!parent_status; + parent_timedout = !!child_status; + child_timedout = !!parent_status; pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, pid); + ASSERT_RETURN_VAL(pid,>=,0, pid); if (pid == 0) { struct kdbus_conn *conn_src; - ret = prctl(PR_SET_PDEATHSIG, SIGKILL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(prctl(PR_SET_PDEATHSIG, SIGKILL)); - ret = drop_privileges(65534, 65534); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(drop_privileges(65534, 65534)); - conn_src = kdbus_hello(bus, 0, NULL, 0); - ASSERT_EXIT(conn_src); + ASSERT_EXIT_NONZERO(conn_src = kdbus_hello(bus, 0, NULL, 0)); - ret = kdbus_add_match_empty(conn_src); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_add_match_empty(conn_src)); /* * child_status is always checked against send * operations, in case it fails always return * EXIT_FAILURE. */ - ret = kdbus_msg_send(conn_src, NULL, cookie, - 0, 0, 0, conn_db[0]->id, 0, NULL); - ASSERT_EXIT(ret == child_status); + ASSERT_EXIT(child_status,==,kdbus_msg_send(conn_src, NULL, cookie, 0, 0, 0, conn_db[0]->id)); - ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL); + ret = kdbus_msg_recv_poll(conn_src, 1009, NULL, NULL); kdbus_conn_free(conn_src); @@ -308,12 +300,12 @@ static int kdbus_fork_test_by_id(const char *bus, * value. */ if (child_timedout) - _exit(ret == -ETIMEDOUT ? EXIT_SUCCESS : EXIT_FAILURE); + exit(ret == -ETIMEDOUT ? EXIT_SUCCESS : EXIT_FAILURE); - _exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); + exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } - ret = kdbus_msg_recv_poll(conn_db[0], 100, &msg, &offset); + ret = kdbus_msg_recv_poll(conn_db[0], 1009, &msg, &offset); /* * If parent_timedout is set then this should fail with * -ETIMEDOUT since the child_status was set to a non @@ -321,29 +313,27 @@ static int kdbus_fork_test_by_id(const char *bus, * that kdbus_msg_recv_poll() has succeeded. */ if (parent_timedout) { - ASSERT_RETURN_VAL(ret == -ETIMEDOUT, TEST_ERR); + ASSERT_RETURN_VAL(ret,==,-ETIMEDOUT, TEST_ERR); /* timedout no need to continue, we don't have the * child connection ID, so just terminate. */ goto out; - } else { - ASSERT_RETURN_VAL(ret == 0, ret); - } + } else + ASSERT_RETURN_VAL(ret,==,0, ret); - ret = kdbus_msg_send(conn_db[0], NULL, ++cookie, - 0, 0, 0, msg->src_id, 0, NULL); + ret = kdbus_msg_send(conn_db[0], NULL, ++cookie, 0, 0, 0, msg->src_id); /* * parent_status is checked against send operations, * on failures always return TEST_ERR. */ - ASSERT_RETURN_VAL(ret == parent_status, TEST_ERR); + ASSERT_RETURN_VAL(ret,==,parent_status, TEST_ERR); kdbus_msg_free(msg); - kdbus_free(conn_db[0], offset); + ASSERT_ZERO(kdbus_free(conn_db[0], offset)); out: ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR; } @@ -353,7 +343,7 @@ out: * we return TEST_OK only if the children return with the expected * 'expected_status' that is specified as an argument. */ -static int kdbus_fork_test(const char *bus, const char *name, +static wur int kdbus_fork_test(const char *bus, const char *name, struct kdbus_conn **conn_db, int expected_status) { pid_t pid; @@ -361,29 +351,25 @@ static int kdbus_fork_test(const char *bus, const char *name, int status = 0; pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, pid); + ASSERT_RETURN_VAL(pid,>=,0, pid); if (pid == 0) { - ret = prctl(PR_SET_PDEATHSIG, SIGKILL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(prctl(PR_SET_PDEATHSIG, SIGKILL)); - ret = drop_privileges(65534, 65534); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(drop_privileges(65534, 65534)); ret = kdbus_recv_in_threads(bus, name, conn_db); - _exit(ret == expected_status ? EXIT_SUCCESS : EXIT_FAILURE); + exit(ret == expected_status ? EXIT_SUCCESS : EXIT_FAILURE); } - ret = waitpid(pid, &status, 0); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(0,<=,waitpid(pid, &status, 0)); return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR; } /* Return EXIT_SUCCESS, EXIT_FAILURE or negative errno */ -static int __kdbus_clone_userns_test(const char *bus, +static wur int __kdbus_clone_userns_test(const char *bus, const char *name, - struct kdbus_conn **conn_db, int expected_status) { int efd; @@ -393,7 +379,7 @@ static int __kdbus_clone_userns_test(const char *bus, int status; ret = drop_privileges(uid, uid); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); /* * Since we just dropped privileges, the dumpable flag was just @@ -409,11 +395,11 @@ static int __kdbus_clone_userns_test(const char *bus, * namespace. */ ret = prctl(PR_SET_DUMPABLE, SUID_DUMP_USER); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); /* sync parent/child */ efd = eventfd(0, EFD_CLOEXEC); - ASSERT_RETURN_VAL(efd >= 0, efd); + ASSERT_RETURN_VAL(efd,>=,0, efd); pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWUSER, NULL); if (pid < 0) { @@ -440,42 +426,38 @@ static int __kdbus_clone_userns_test(const char *bus, struct kdbus_conn *conn_src; eventfd_t event_status = 0; - ret = prctl(PR_SET_PDEATHSIG, SIGKILL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(prctl(PR_SET_PDEATHSIG, SIGKILL)); - ret = eventfd_read(efd, &event_status); - ASSERT_EXIT(ret >= 0 && event_status == 1); + ASSERT_EXIT(0,<=,eventfd_read(efd, &event_status)); + ASSERT_EXIT(event_status,==,(eventfd_t)1); /* ping connection from the new user namespace */ - conn_src = kdbus_hello(bus, 0, NULL, 0); - ASSERT_EXIT(conn_src); + ASSERT_EXIT_NONZERO(conn_src = kdbus_hello(bus, 0, NULL, 0)); - ret = kdbus_add_match_empty(conn_src); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_add_match_empty(conn_src)); - ret = kdbus_msg_send(conn_src, name, 0xabcd1234, - 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL); + ret = kdbus_msg_send(conn_src, name, 0xabcd1234, 0, 0, 0, KDBUS_DST_ID_NAME); kdbus_conn_free(conn_src); - _exit(ret == expected_status ? EXIT_SUCCESS : EXIT_FAILURE); + exit(ret == expected_status ? EXIT_SUCCESS : EXIT_FAILURE); } ret = userns_map_uid_gid(pid, "0 65534 1", "0 65534 1"); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); /* Tell child we are ready */ ret = eventfd_write(efd, 1); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); - close(efd); + CLOSE(efd); return status == EXIT_SUCCESS ? TEST_OK : TEST_ERR; } -static int kdbus_clone_userns_test(const char *bus, +static wur int kdbus_clone_userns_test(const char *bus, const char *name, struct kdbus_conn **conn_db, int expected_status) @@ -485,32 +467,30 @@ static int kdbus_clone_userns_test(const char *bus, int status; pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, -errno); + ASSERT_RETURN_VAL(pid,>=,0, -errno); if (pid == 0) { ret = prctl(PR_SET_PDEATHSIG, SIGKILL); if (ret < 0) - _exit(EXIT_FAILURE); + exit(EXIT_FAILURE); - ret = __kdbus_clone_userns_test(bus, name, conn_db, - expected_status); - _exit(ret); + exit(__kdbus_clone_userns_test(bus, name, expected_status)); } /* * Receive in the original (root privileged) user namespace, * must fail with -ETIMEDOUT. */ - ret = kdbus_msg_recv_poll(conn_db[0], 100, NULL, NULL); - ASSERT_RETURN_VAL(ret == -ETIMEDOUT, ret); + ret = kdbus_msg_recv_poll(conn_db[0], 1009, NULL, NULL); + ASSERT_RETURN(ret,==,expected_status?-ETIMEDOUT:0); ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN(ret,>=,0); return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR; } -int kdbus_test_policy_ns(struct kdbus_test_env *env) +wur int kdbus_test_policy_ns(struct kdbus_test_env *env) { int i; int ret; @@ -519,7 +499,7 @@ int kdbus_test_policy_ns(struct kdbus_test_env *env) char *bus = env->buspath; ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); /* no enough privileges, SKIP test */ if (!ret) @@ -533,44 +513,29 @@ int kdbus_test_policy_ns(struct kdbus_test_env *env) if (!all_uids_gids_are_mapped()) return TEST_SKIP; - conn_db = calloc(MAX_CONN, sizeof(struct kdbus_conn *)); - ASSERT_RETURN(conn_db); + ASSERT_NONZERO(conn_db = calloc(MAX_CONN, sizeof(struct kdbus_conn *))); memset(conn_db, 0, MAX_CONN * sizeof(struct kdbus_conn *)); - conn_db[0] = kdbus_hello(bus, 0, NULL, 0); - ASSERT_RETURN(conn_db[0]); + ASSERT_NONZERO(conn_db[0] = kdbus_hello(bus, 0, NULL, 0)); - ret = kdbus_add_match_empty(conn_db[0]); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn_db[0])); - ret = kdbus_fork_test_by_id(bus, conn_db, -EPERM, -EPERM); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_fork_test_by_id(bus, conn_db, -EPERM, -EPERM)); - ret = kdbus_register_policy_holder(bus, POLICY_NAME, - &policy_holder); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_register_policy_holder(bus, POLICY_NAME, &policy_holder)); /* Try to register the same name with an activator */ - ret = kdbus_register_same_activator(bus, POLICY_NAME, - &activator); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_register_same_activator(bus, POLICY_NAME, &activator)); /* Acquire POLICY_NAME */ - ret = kdbus_name_acquire(conn_db[0], POLICY_NAME, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_name_acquire(conn_db[0], POLICY_NAME, NULL)); - ret = kdbus_normal_test(bus, POLICY_NAME, conn_db); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_normal_test(bus, POLICY_NAME, conn_db)); - ret = kdbus_list(conn_db[0], KDBUS_LIST_NAMES | - KDBUS_LIST_UNIQUE | - KDBUS_LIST_ACTIVATORS | - KDBUS_LIST_QUEUED); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_list(conn_db[0], KDBUS_LIST_NAMES | KDBUS_LIST_UNIQUE | KDBUS_LIST_ACTIVATORS | KDBUS_LIST_QUEUED)); - ret = kdbus_fork_test(bus, POLICY_NAME, conn_db, EXIT_SUCCESS); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_fork_test(bus, POLICY_NAME, conn_db, EXIT_SUCCESS)); /* * children connections are able to talk to conn_db[0] since @@ -581,9 +546,7 @@ int kdbus_test_policy_ns(struct kdbus_test_env *env) * -EPERM but since it is a privileged bus user the TALK is * allowed. */ - ret = kdbus_fork_test_by_id(bus, conn_db, - EXIT_SUCCESS, EXIT_SUCCESS); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_fork_test_by_id(bus, conn_db, EXIT_SUCCESS, EXIT_SUCCESS)); /* * Connections that can talk are perhaps being destroyed now. @@ -592,17 +555,14 @@ int kdbus_test_policy_ns(struct kdbus_test_env *env) * * Now only connections with uid == 0 are allowed to talk. */ - ret = kdbus_set_policy_talk(policy_holder, POLICY_NAME, - geteuid(), KDBUS_POLICY_ACCESS_USER); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_set_policy_talk(policy_holder, POLICY_NAME, geteuid(), KDBUS_POLICY_ACCESS_USER)); /* * Testing connections (FORK+DROP) again: * After setting the policy re-check connections * we expect the children to fail with -EPERM */ - ret = kdbus_fork_test(bus, POLICY_NAME, conn_db, -EPERM); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_fork_test(bus, POLICY_NAME, conn_db, ONTIZEN(0,-EPERM))); /* * Now expect that both parent and child to fail. @@ -613,12 +573,10 @@ int kdbus_test_policy_ns(struct kdbus_test_env *env) * Since the parent's connection will timeout when receiving * from the child, we never continue. FWIW just put -EPERM. */ - ret = kdbus_fork_test_by_id(bus, conn_db, -EPERM, -EPERM); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_fork_test_by_id(bus, conn_db, -EPERM, -EPERM)); /* Check if the name can be reached in a new userns */ - ret = kdbus_clone_userns_test(bus, POLICY_NAME, conn_db, -EPERM); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_clone_userns_test(bus, POLICY_NAME, conn_db, ONTIZEN(0,-EPERM))); for (i = 0; i < MAX_CONN; i++) kdbus_conn_free(conn_db[i]); @@ -628,5 +586,5 @@ int kdbus_test_policy_ns(struct kdbus_test_env *env) free(conn_db); - return ret; + return TEST_OK; } diff --git a/tools/testing/selftests/kdbus/test-policy-priv.c b/tools/testing/selftests/kdbus/test-policy-priv.c index 14a09c6..0d9d476 100644 --- a/tools/testing/selftests/kdbus/test-policy-priv.c +++ b/tools/testing/selftests/kdbus/test-policy-priv.c @@ -15,32 +15,29 @@ #include "kdbus-util.h" #include "kdbus-enum.h" -static int test_policy_priv_by_id(const char *bus, +static wur int test_policy_priv_by_id(const char *bus, struct kdbus_conn *conn_dst, - bool drop_second_user, int parent_status, int child_status) { - int ret = 0; uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef; - ASSERT_RETURN(conn_dst); +#ifdef TIZEN + parent_status = child_status = 0; +#endif + + ASSERT_NONZERO(conn_dst); - ret = RUN_UNPRIVILEGED_CONN(unpriv, bus, ({ - ret = kdbus_msg_send(unpriv, NULL, - expected_cookie, 0, 0, 0, - conn_dst->id, 0, NULL); - ASSERT_EXIT(ret == child_status); + RUN_UNPRIVILEGED_CONN(unpriv, bus, ({ + ASSERT_EXIT(child_status,==,kdbus_msg_send(unpriv, NULL, expected_cookie, 0, 0, 0, conn_dst->id)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_msg_recv_poll(conn_dst, 300, NULL, NULL); - ASSERT_RETURN(ret == parent_status); + ASSERT_RETURN(parent_status,==,kdbus_msg_recv_poll(conn_dst, 300, NULL, NULL)); return 0; } -static int test_policy_priv_by_broadcast(const char *bus, +static wur int test_policy_priv_by_broadcast(const char *bus, struct kdbus_conn *conn_dst, int drop_second_user, int parent_status, @@ -55,6 +52,12 @@ static int test_policy_priv_by_broadcast(const char *bus, struct kdbus_conn *child_2 = conn_dst; uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef; +#ifdef TIZEN + child_status = 0; + if (DO_NOT_DROP != drop_second_user) + parent_status = 0; +#endif + /* Drop to another unprivileged user other than UNPRIV_UID */ if (drop_second_user == DROP_OTHER_UNPRIV) { second_uid = UNPRIV_UID - 1; @@ -63,141 +66,112 @@ static int test_policy_priv_by_broadcast(const char *bus, /* child will signal parent to send broadcast */ efd = eventfd(0, EFD_CLOEXEC); - ASSERT_RETURN_VAL(efd >= 0, efd); + ASSERT_RETURN_VAL(efd,>=,0, efd); - ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ + RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ struct kdbus_conn *child; - child = kdbus_hello(bus, 0, NULL, 0); - ASSERT_EXIT(child); + ASSERT_EXIT_NONZERO(child = kdbus_hello(bus, 0, NULL, 0)); - ret = kdbus_add_match_empty(child); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_add_match_empty(child)); /* signal parent */ - ret = eventfd_write(efd, 1); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(eventfd_write(efd, 1)); /* Use a little bit high time */ - ret = kdbus_msg_recv_poll(child, 500, &msg, NULL); - ASSERT_EXIT(ret == child_status); + ASSERT_EXIT(child_status,==,kdbus_msg_recv_poll(child, 500, &msg, NULL)); /* * If we expect the child to get the broadcast * message, then check the received cookie. */ - if (ret == 0) { - ASSERT_EXIT(expected_cookie == msg->cookie); + if (!child_status) { + ASSERT_EXIT(expected_cookie,==,msg->cookie); + kdbus_msg_free(msg); } /* Use expected_cookie since 'msg' might be NULL */ - ret = kdbus_msg_send(child, NULL, expected_cookie + 1, - 0, 0, 0, KDBUS_DST_ID_BROADCAST, - 0, NULL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_msg_send(child, NULL, expected_cookie + 1, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); - kdbus_msg_free(msg); kdbus_conn_free(child); }), ({ - if (drop_second_user == DO_NOT_DROP) { - ASSERT_RETURN(child_2); - - ret = eventfd_read(efd, &event_status); - ASSERT_RETURN(ret >= 0 && event_status == 1); + bool got_own_broadcast = 0; + #define RECEIVE_FROM_PARENT() for (;;) {\ + /* Use a little bit high time */\ + ret = kdbus_msg_recv_poll(child_2, 1000, &msg, NULL);\ + if (!ret && child_2->id == msg->src_id) {\ + ASSERT_ZERO(got_own_broadcast);\ + got_own_broadcast = 1;\ + kdbus_msg_free(msg);\ + continue;\ + }\ + ASSERT_RETURN(parent_status,==,ret);\ + /* Check returned cookie in case we expect success. */\ + if (!ret) {\ + ASSERT_RETURN(msg->cookie,==,expected_cookie + 1);\ + kdbus_msg_free(msg);\ + }\ + break;\ + } - ret = kdbus_msg_send(child_2, NULL, - expected_cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, - 0, NULL); - ASSERT_RETURN(ret == 0); + if (drop_second_user == DO_NOT_DROP) { + ASSERT_NONZERO(child_2); - /* Use a little bit high time */ - ret = kdbus_msg_recv_poll(child_2, 1000, - &msg, NULL); - ASSERT_RETURN(ret == parent_status); + ASSERT_RETURN(0,<=,eventfd_read(efd, &event_status)); + ASSERT_RETURN(event_status,==,(eventfd_t)1); - /* - * Check returned cookie in case we expect - * success. - */ - if (ret == 0) { - ASSERT_RETURN(msg->cookie == - expected_cookie + 1); - } + ASSERT_ZERO(kdbus_msg_send(child_2, NULL, expected_cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); - kdbus_msg_free(msg); + RECEIVE_FROM_PARENT(); } else { /* * Two unprivileged users will try to * communicate using broadcast. */ - ret = RUN_UNPRIVILEGED(second_uid, second_gid, ({ - child_2 = kdbus_hello(bus, 0, NULL, 0); - ASSERT_EXIT(child_2); - - ret = kdbus_add_match_empty(child_2); - ASSERT_EXIT(ret == 0); - - ret = eventfd_read(efd, &event_status); - ASSERT_EXIT(ret >= 0 && event_status == 1); - - ret = kdbus_msg_send(child_2, NULL, - expected_cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, - 0, NULL); - ASSERT_EXIT(ret == 0); - - /* Use a little bit high time */ - ret = kdbus_msg_recv_poll(child_2, 1000, - &msg, NULL); - ASSERT_EXIT(ret == parent_status); - - /* - * Check returned cookie in case we expect - * success. - */ - if (ret == 0) { - ASSERT_EXIT(msg->cookie == - expected_cookie + 1); - } - - kdbus_msg_free(msg); + RUN_UNPRIVILEGED(second_uid, second_gid, ({ + ASSERT_EXIT_NONZERO(child_2 = kdbus_hello(bus, 0, NULL, 0)); + + ASSERT_EXIT_ZERO(kdbus_add_match_empty(child_2)); + + ASSERT_EXIT(0,<=,eventfd_read(efd, &event_status)); + ASSERT_EXIT(event_status,==,(eventfd_t)1); + + ASSERT_EXIT_ZERO(kdbus_msg_send(child_2, NULL, expected_cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); + + RECEIVE_FROM_PARENT(); kdbus_conn_free(child_2); }), - ({ 0; })); - ASSERT_RETURN(ret == 0); + ({})); } })); - ASSERT_RETURN(ret == 0); +#undef RECEIVE_FROM_PARENT - close(efd); + CLOSE(efd); return ret; } static void nosig(int sig) { + UNUSED(sig); } -static int test_priv_before_policy_upload(struct kdbus_test_env *env) +static wur int test_priv_before_policy_upload(struct kdbus_test_env *env) { int ret = 0; struct kdbus_conn *conn; - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* * Make sure unprivileged bus user cannot acquire names - * before registring any policy holder. + * before registering any policy holder. */ - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret < 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(0,ONTIZEN(==,>),kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret == 0); /* * Make sure unprivileged bus users cannot talk by default @@ -205,27 +179,18 @@ static int test_priv_before_policy_upload(struct kdbus_test_env *env) * this was uploaded. */ - ret = test_policy_priv_by_id(env->buspath, conn, false, - -ETIMEDOUT, -EPERM); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_id(env->buspath, conn, -ETIMEDOUT, -EPERM)); /* Activate matching for a privileged connection */ - ret = kdbus_add_match_empty(conn); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn)); /* * First make sure that BROADCAST with msg flag * KDBUS_MSG_EXPECT_REPLY will fail with -ENOTUNIQ */ - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef, - KDBUS_MSG_EXPECT_REPLY, - 5000000000ULL, 0, - KDBUS_DST_ID_BROADCAST, - 0, NULL); - ASSERT_EXIT(ret == -ENOTUNIQ); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(-ENOTUNIQ,==,kdbus_msg_send(unpriv, NULL, 0xdeadbeef, KDBUS_MSG_EXPECT_REPLY, 5000000000ULL, 0, KDBUS_DST_ID_BROADCAST)); })); - ASSERT_RETURN(ret == 0); /* * Test broadcast with a privileged connection. @@ -243,10 +208,7 @@ static int test_priv_before_policy_upload(struct kdbus_test_env *env) * all connections it will receive those. */ - ret = test_policy_priv_by_broadcast(env->buspath, conn, - DO_NOT_DROP, - 0, -ETIMEDOUT); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, conn, DO_NOT_DROP, 0, -ETIMEDOUT)); /* @@ -256,9 +218,7 @@ static int test_priv_before_policy_upload(struct kdbus_test_env *env) * Both connections should succeed. */ - ret = test_policy_priv_by_broadcast(env->buspath, NULL, - DROP_SAME_UNPRIV, 0, 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, NULL, DROP_SAME_UNPRIV, 0, 0)); /* * Test broadcast with two unprivileged connections running @@ -267,19 +227,15 @@ static int test_priv_before_policy_upload(struct kdbus_test_env *env) * Both connections will fail with -ETIMEDOUT. */ - ret = test_policy_priv_by_broadcast(env->buspath, NULL, - DROP_OTHER_UNPRIV, - -ETIMEDOUT, -ETIMEDOUT); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, NULL, DROP_OTHER_UNPRIV, -ETIMEDOUT, -ETIMEDOUT)); kdbus_conn_free(conn); return ret; } -static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) +static wur int test_broadcast_after_policy_upload(struct kdbus_test_env *env) { - int ret; int efd; eventfd_t event_status = 0; struct kdbus_msg *msg = NULL; @@ -288,11 +244,9 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) struct kdbus_policy_access access = {}; uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef; - owner_a = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(owner_a); + ASSERT_NONZERO(owner_a = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL)); /* * Make sure unprivileged bus users cannot talk by default @@ -301,9 +255,7 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) */ ++expected_cookie; - ret = test_policy_priv_by_id(env->buspath, owner_a, false, - -ETIMEDOUT, -EPERM); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_id(env->buspath, owner_a, -ETIMEDOUT, -EPERM)); /* * Make sure that privileged won't receive broadcasts unless @@ -316,15 +268,10 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) * registered so we fail by default), thus the unprivileged * receiver is not able to TALK to that name. */ - - ret = test_policy_priv_by_broadcast(env->buspath, owner_a, - DO_NOT_DROP, - -ETIMEDOUT, -ETIMEDOUT); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, owner_a, DO_NOT_DROP, -ETIMEDOUT, -ETIMEDOUT)); /* Activate matching for a privileged connection */ - ret = kdbus_add_match_empty(owner_a); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(owner_a)); /* * Redo the previous test. The privileged conn owner_a is @@ -332,19 +279,14 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) * broadcast message now. */ - ret = test_policy_priv_by_broadcast(env->buspath, owner_a, - DO_NOT_DROP, - 0, -ETIMEDOUT); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, owner_a, DO_NOT_DROP, 0, -ETIMEDOUT)); /* * Test that broadcast between two unprivileged users running * under the same user still succeed. */ - ret = test_policy_priv_by_broadcast(env->buspath, NULL, - DROP_SAME_UNPRIV, 0, 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, NULL, DROP_SAME_UNPRIV, 0, 0)); /* * Test broadcast with two unprivileged connections running @@ -353,10 +295,7 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) * Both connections will fail with -ETIMEDOUT. */ - ret = test_policy_priv_by_broadcast(env->buspath, NULL, - DROP_OTHER_UNPRIV, - -ETIMEDOUT, -ETIMEDOUT); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, NULL, DROP_OTHER_UNPRIV, -ETIMEDOUT, -ETIMEDOUT)); access = (struct kdbus_policy_access){ .type = KDBUS_POLICY_ACCESS_USER, @@ -364,40 +303,25 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - holder_a = kdbus_hello_registrar(env->buspath, - "com.example.broadcastA", - &access, 1, - KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(holder_a); - - holder_b = kdbus_hello_registrar(env->buspath, - "com.example.broadcastB", - &access, 1, - KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(holder_b); + ASSERT_NONZERO(holder_a = kdbus_hello_registrar(env->buspath, "com.example.broadcastA", &access, 1, KDBUS_HELLO_POLICY_HOLDER)); + ASSERT_NONZERO(holder_b = kdbus_hello_registrar(env->buspath, "com.example.broadcastB", &access, 1, KDBUS_HELLO_POLICY_HOLDER)); /* Free connections and their received messages and restart */ kdbus_conn_free(owner_a); - owner_a = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(owner_a); + ASSERT_NONZERO(owner_a = kdbus_hello(env->buspath, 0, NULL, 0)); /* Activate matching for a privileged connection */ - ret = kdbus_add_match_empty(owner_a); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(owner_a)); - ret = kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL)); - owner_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(owner_b); + ASSERT_NONZERO(owner_b = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_name_acquire(owner_b, "com.example.broadcastB", NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_acquire(owner_b, "com.example.broadcastB", NULL)); /* Activate matching for a privileged connection */ - ret = kdbus_add_match_empty(owner_b); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(owner_b)); /* * Test that even if "com.example.broadcastA" and @@ -408,23 +332,23 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) */ ++expected_cookie; - ret = kdbus_msg_send(owner_a, NULL, expected_cookie, 0, - 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); - - ret = kdbus_msg_recv_poll(owner_b, 100, &msg, NULL); - ASSERT_RETURN(ret == 0); - ASSERT_RETURN(msg->cookie == expected_cookie); + ASSERT_ZERO(kdbus_msg_send(owner_a, NULL, expected_cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_b, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,expected_cookie); /* Check src ID */ - ASSERT_RETURN(msg->src_id == owner_a->id); - + ASSERT_RETURN(msg->src_id,==,owner_a->id); kdbus_msg_free(msg); + /* purge self-broadcast */ + ASSERT_ZERO(kdbus_msg_recv_poll(owner_a, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,expected_cookie); + /* Check src ID */ + ASSERT_RETURN(msg->src_id,==,owner_a->id); + /* Release name "com.example.broadcastB" */ - ret = kdbus_name_release(owner_b, "com.example.broadcastB"); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_release(owner_b, "com.example.broadcastB")); /* KDBUS_POLICY_OWN for unprivileged connections */ access = (struct kdbus_policy_access){ @@ -435,10 +359,7 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) /* Update the policy so unprivileged will own the name */ - ret = kdbus_conn_update_policy(holder_b, - "com.example.broadcastB", - &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(holder_b, "com.example.broadcastB", &access, 1)); /* * Send broadcasts from an unprivileged connection that @@ -469,72 +390,55 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) ++expected_cookie; efd = eventfd(0, EFD_CLOEXEC); - ASSERT_RETURN_VAL(efd >= 0, efd); + ASSERT_RETURN_VAL(efd,>=,0, efd); - ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({ + RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({ struct kdbus_conn *unpriv_owner; struct kdbus_conn *unpriv_a, *unpriv_b; - unpriv_owner = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_EXIT(unpriv_owner); - - unpriv_a = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_EXIT(unpriv_a); + ASSERT_EXIT_NONZERO(unpriv_owner = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_EXIT_NONZERO(unpriv_a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_EXIT_NONZERO(unpriv_b = kdbus_hello(env->buspath, 0, NULL, 0)); - unpriv_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_EXIT(unpriv_b); + ASSERT_EXIT_ZERO(kdbus_name_acquire(unpriv_owner, "com.example.broadcastB", NULL)); - ret = kdbus_name_acquire(unpriv_owner, - "com.example.broadcastB", - NULL); - ASSERT_EXIT(ret >= 0); - - ret = kdbus_add_match_empty(unpriv_a); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_add_match_empty(unpriv_a)); /* Signal that we are doing broadcasts */ - ret = eventfd_write(efd, 1); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(eventfd_write(efd, 1)); /* * Do broadcast from a connection that owns the * names "com.example.broadcastB". */ - ret = kdbus_msg_send(unpriv_owner, NULL, - expected_cookie, - 0, 0, 0, - KDBUS_DST_ID_BROADCAST, - 0, NULL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv_owner, NULL, expected_cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); /* * Unprivileged connection running under the same * user. It should succeed. */ - ret = kdbus_msg_recv_poll(unpriv_a, 300, &msg, NULL); - ASSERT_EXIT(ret == 0 && msg->cookie == expected_cookie); + ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(unpriv_a, 300, &msg, NULL)); + ASSERT_EXIT(msg->cookie,==,expected_cookie); /* * Did not install matches, not interested in * broadcasts */ - ret = kdbus_msg_recv_poll(unpriv_b, 300, NULL, NULL); - ASSERT_EXIT(ret == -ETIMEDOUT); + ASSERT_EXIT(-ETIMEDOUT,==,kdbus_msg_recv_poll(unpriv_b, 300, NULL, NULL)); }), ({ - ret = eventfd_read(efd, &event_status); - ASSERT_RETURN(ret >= 0 && event_status == 1); + ASSERT_RETURN(0,<=,eventfd_read(efd, &event_status)); + ASSERT_RETURN(event_status,==,(eventfd_t)1); /* * owner_a must fail with -ETIMEDOUT, since it owns * name "com.example.broadcastA" and its TALK * access is restriced. */ - ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_a, 300, &msg, NULL)); /* confirm the received cookie */ - ASSERT_RETURN(msg->cookie == expected_cookie); + ASSERT_RETURN(msg->cookie,==,expected_cookie); kdbus_msg_free(msg); @@ -542,18 +446,16 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) * owner_b got the broadcast from an unprivileged * connection. */ - ret = kdbus_msg_recv_poll(owner_b, 300, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_b, 300, &msg, NULL)); /* confirm the received cookie */ - ASSERT_RETURN(msg->cookie == expected_cookie); + ASSERT_RETURN(msg->cookie,==,expected_cookie); kdbus_msg_free(msg); })); - ASSERT_RETURN(ret == 0); - close(efd); + CLOSE(efd); /* * Test broadcast with two unprivileged connections running @@ -562,25 +464,18 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) * Both connections will fail with -ETIMEDOUT. */ - ret = test_policy_priv_by_broadcast(env->buspath, NULL, - DROP_OTHER_UNPRIV, - -ETIMEDOUT, -ETIMEDOUT); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, NULL, DROP_OTHER_UNPRIV, -ETIMEDOUT, -ETIMEDOUT)); /* Drop received broadcasts by privileged */ - ret = kdbus_msg_recv_poll(owner_a, 100, NULL, NULL); - ret = kdbus_msg_recv_poll(owner_a, 100, NULL, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_a, 100, NULL, NULL)); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_a, 100, NULL, NULL)); - ret = kdbus_msg_recv(owner_a, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(owner_a, NULL, NULL)); - ret = kdbus_msg_recv_poll(owner_b, 100, NULL, NULL); - ret = kdbus_msg_recv_poll(owner_b, 100, NULL, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_b, 100, NULL, NULL)); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_b, 100, NULL, NULL)); - ret = kdbus_msg_recv(owner_b, NULL, NULL); - ASSERT_RETURN(ret == -EAGAIN); + ASSERT_RETURN(-EAGAIN,==,kdbus_msg_recv(owner_b, NULL, NULL)); /* * Perform last tests, allow others to talk to name @@ -595,36 +490,25 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) .access = KDBUS_POLICY_TALK, }; - ret = kdbus_conn_update_policy(holder_a, - "com.example.broadcastA", - &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(holder_a, "com.example.broadcastA", &access, 1)); /* * Unprivileged is able to TALK to "com.example.broadcastA" * now so it will receive its broadcasts */ - ret = test_policy_priv_by_broadcast(env->buspath, owner_a, - DO_NOT_DROP, 0, 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_policy_priv_by_broadcast(env->buspath, owner_a, DO_NOT_DROP, 0, 0)); ++expected_cookie; - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.broadcastB", - NULL); - ASSERT_EXIT(ret >= 0); - ret = kdbus_msg_send(unpriv, NULL, expected_cookie, - 0, 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_EXIT(ret == 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_name_acquire(unpriv, "com.example.broadcastB", NULL)); + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, NULL, expected_cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); })); - ASSERT_RETURN(ret == 0); /* owner_a is privileged it will get the broadcast now. */ - ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_a, 300, &msg, NULL)); /* confirm the received cookie */ - ASSERT_RETURN(msg->cookie == expected_cookie); + ASSERT_RETURN(msg->cookie,==,expected_cookie); kdbus_msg_free(msg); @@ -637,26 +521,19 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) * signal to the privileged connection. */ - ret = kdbus_name_release(owner_a, "com.example.broadcastA"); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_release(owner_a, "com.example.broadcastA")); ++expected_cookie; - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.broadcastB", - NULL); - ASSERT_EXIT(ret >= 0); - ret = kdbus_msg_send(unpriv, NULL, expected_cookie, - 0, 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_EXIT(ret == 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_name_acquire(unpriv, "com.example.broadcastB", NULL)); + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, NULL, expected_cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); })); - ASSERT_RETURN(ret == 0); /* owner_a will get the broadcast now. */ - ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_recv_poll(owner_a, 300, &msg, NULL)); /* confirm the received cookie */ - ASSERT_RETURN(msg->cookie == expected_cookie); + ASSERT_RETURN(msg->cookie,==,expected_cookie); kdbus_msg_free(msg); @@ -668,7 +545,7 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env) return 0; } -static int test_policy_priv(struct kdbus_test_env *env) +static wur int test_policy_priv(struct kdbus_test_env *env) { struct kdbus_conn *conn_a, *conn_b, *conn, *owner; struct kdbus_policy_access access, *acc; @@ -681,7 +558,7 @@ static int test_policy_priv(struct kdbus_test_env *env) */ ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1); - ASSERT_RETURN(ret >= 0); + ASSERT_RETURN(ret,>=,0); if (!ret) return TEST_SKIP; @@ -701,8 +578,7 @@ static int test_policy_priv(struct kdbus_test_env *env) sigaddset(&sset, SIGUSR1); sigprocmask(SIG_BLOCK, &sset, NULL); - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); /* * Before registering any policy holder, make sure that the @@ -710,43 +586,36 @@ static int test_policy_priv(struct kdbus_test_env *env) * several cases where old D-Bus was vulnerable. */ - ret = test_priv_before_policy_upload(env); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_priv_before_policy_upload(env)); /* * Make sure unprivileged are not able to register policy * holders */ - ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ + RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ struct kdbus_conn *holder; holder = kdbus_hello_registrar(env->buspath, "com.example.a", NULL, 0, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_EXIT(holder == NULL && errno == EPERM); + ASSERT_EXIT(errno,==,EPERM); + ASSERT_ZERO(holder); }), - ({ 0; })); - ASSERT_RETURN(ret == 0); + ({})); /* Register policy holder */ - conn_a = kdbus_hello_registrar(env->buspath, "com.example.a", - NULL, 0, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(conn_a); - - conn_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_b); + ASSERT_NONZERO(conn_a = kdbus_hello_registrar(env->buspath, "com.example.a", NULL, 0, KDBUS_HELLO_POLICY_HOLDER)); + ASSERT_NONZERO(conn_b = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_name_acquire(conn_b, "com.example.b", NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_acquire(conn_b, "com.example.b", NULL)); /* * Make sure bus-owners can always acquire names. */ - ret = kdbus_name_acquire(conn, "com.example.a", NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_acquire(conn, "com.example.a", NULL)); kdbus_conn_free(conn); @@ -755,11 +624,9 @@ static int test_policy_priv(struct kdbus_test_env *env) * policy assigned. */ - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret < 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(0,ONTIZEN(==,!=),kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged users can acquire names if we make them @@ -777,21 +644,15 @@ static int test_policy_priv(struct kdbus_test_env *env) * to update policies */ - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_conn_update_policy(unpriv, "com.example.a", - &access, 1); - ASSERT_EXIT(ret == -EOPNOTSUPP); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(-EOPNOTSUPP,==,kdbus_conn_update_policy(unpriv, "com.example.a", &access, 1)); })); - ASSERT_RETURN(ret == 0); - ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged users can acquire names if we make them @@ -804,14 +665,11 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); access = (struct kdbus_policy_access){ .type = KDBUS_POLICY_ACCESS_GROUP, @@ -819,14 +677,11 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret < 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(0,ONTIZEN(==,!=),kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged users can acquire names if we make them @@ -839,14 +694,11 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); access = (struct kdbus_policy_access){ .type = KDBUS_POLICY_ACCESS_USER, @@ -854,14 +706,11 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret < 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(0,ONTIZEN(==,!=),kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged users cannot acquire names if no owner-policy @@ -892,14 +741,11 @@ static int test_policy_priv(struct kdbus_test_env *env) }, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.a", acc, num); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", acc, num)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret < 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(0,ONTIZEN(==,!=),kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged users can acquire names if the only matching @@ -935,35 +781,27 @@ static int test_policy_priv(struct kdbus_test_env *env) }, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.a", acc, num); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", acc, num)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_name_acquire(unpriv, "com.example.a", NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_name_acquire(unpriv, "com.example.a", NULL)); })); - ASSERT_RETURN(ret >= 0); /* * Clear policies */ - ret = kdbus_conn_update_policy(conn_a, "com.example.a", NULL, 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", NULL, 0)); /* * Make sure privileged bus users can _always_ talk to others. */ - conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_msg_send(conn, "com.example.b", 0xdeadbeef, 0, 0, 0, 0, - 0, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_msg_send(conn, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); - ret = kdbus_msg_recv_poll(conn_b, 300, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(conn_b, 300, NULL, NULL)); kdbus_conn_free(conn); @@ -971,12 +809,9 @@ static int test_policy_priv(struct kdbus_test_env *env) * Make sure unprivileged bus users cannot talk by default. */ - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret == -EPERM); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(ONTIZEN(0,-EPERM),==,kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged bus users can talk to equals, even without @@ -989,27 +824,20 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.c", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.c", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ struct kdbus_conn *owner; - owner = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(owner); + ASSERT_NONZERO(owner = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_name_acquire(owner, "com.example.c", NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_name_acquire(owner, "com.example.c", NULL)); - ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret >= 0); - ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_ZERO(kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0, 0, 0)); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(owner, 100, NULL, NULL)); kdbus_conn_free(owner); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged bus users can talk to privileged users if a @@ -1022,18 +850,13 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_TALK, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(conn_b, 100, NULL, NULL)); /* * Make sure unprivileged bus users can talk to privileged users if a @@ -1046,18 +869,13 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_TALK, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(conn_b, 100, NULL, NULL)); /* * Make sure unprivileged bus users can talk to privileged users if a @@ -1070,18 +888,13 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_TALK, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(conn_b, 100, NULL, NULL)); /* * Make sure unprivileged bus users cannot talk to privileged users if @@ -1117,15 +930,11 @@ static int test_policy_priv(struct kdbus_test_env *env) }, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.b", acc, num); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.b", acc, num)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret == -EPERM); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT(ONTIZEN(0,-EPERM),==,kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure unprivileged bus users can talk to privileged users if a @@ -1138,18 +947,13 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); })); - ASSERT_RETURN(ret >= 0); - ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(conn_b, 100, NULL, NULL)); /* * Make sure the TALK cache is reset correctly when policies are @@ -1162,26 +966,17 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_TALK, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1)); - ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret >= 0); + RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); - ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(conn_b, 100, NULL, NULL)); - ret = kdbus_conn_update_policy(conn_a, "com.example.b", - NULL, 0); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.b", NULL, 0)); - ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret == -EPERM); + ASSERT_EXIT(ONTIZEN(0,-EPERM),==,kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0, 0, 0)); })); - ASSERT_RETURN(ret >= 0); /* * Make sure the TALK cache is reset correctly when policy holders @@ -1194,43 +989,33 @@ static int test_policy_priv(struct kdbus_test_env *env) .access = KDBUS_POLICY_OWN, }; - conn = kdbus_hello_registrar(env->buspath, "com.example.c", - NULL, 0, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(conn); + ASSERT_NONZERO(conn = kdbus_hello_registrar(env->buspath, "com.example.c", NULL, 0, KDBUS_HELLO_POLICY_HOLDER)); - ret = kdbus_conn_update_policy(conn, "com.example.c", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn, "com.example.c", &access, 1)); - owner = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(owner); + ASSERT_NONZERO(owner = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_name_acquire(owner, "com.example.c", NULL); - ASSERT_RETURN(ret >= 0); + ASSERT_ZERO(kdbus_name_acquire(owner, "com.example.c", NULL)); - ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ + RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({ struct kdbus_conn *unpriv; /* wait for parent to be finished */ sigemptyset(&sset); ret = sigsuspend(&sset); - ASSERT_RETURN(ret == -1 && errno == EINTR); + ASSERT_RETURN(errno,==,EINTR); + ASSERT_RETURN(ret,==,-1); - unpriv = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(unpriv); + ASSERT_NONZERO(unpriv = kdbus_hello(env->buspath, 0, NULL, 0)); - ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT_ZERO(kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0, 0, 0)); - ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL); - ASSERT_EXIT(ret >= 0); + ASSERT_EXIT(0,<=,kdbus_msg_recv_poll(owner, 100, NULL, NULL)); /* free policy holder */ kdbus_conn_free(conn); - ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0, - 0, 0, 0, NULL); - ASSERT_EXIT(ret == -EPERM); + ASSERT_EXIT(ONTIZEN(0,-EPERM),==,kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0, 0, 0)); kdbus_conn_free(unpriv); }), ({ @@ -1238,15 +1023,12 @@ static int test_policy_priv(struct kdbus_test_env *env) kdbus_conn_free(conn); kill(pid, SIGUSR1); })); - ASSERT_RETURN(ret >= 0); - /* * The following tests are necessary. */ - ret = test_broadcast_after_policy_upload(env); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(test_broadcast_after_policy_upload(env)); kdbus_conn_free(owner); @@ -1260,7 +1042,7 @@ static int test_policy_priv(struct kdbus_test_env *env) return TEST_OK; } -int kdbus_test_policy_priv(struct kdbus_test_env *env) +wur int kdbus_test_policy_priv(struct kdbus_test_env *env) { pid_t pid; int ret; diff --git a/tools/testing/selftests/kdbus/test-policy.c b/tools/testing/selftests/kdbus/test-policy.c index 96d20d5..830440b 100644 --- a/tools/testing/selftests/kdbus/test-policy.c +++ b/tools/testing/selftests/kdbus/test-policy.c @@ -11,28 +11,17 @@ #include "kdbus-util.h" #include "kdbus-enum.h" -int kdbus_test_policy(struct kdbus_test_env *env) +wur int kdbus_test_policy(struct kdbus_test_env *env) { struct kdbus_conn *conn_a, *conn_b; struct kdbus_policy_access access; - int ret; /* Invalid name */ - conn_a = kdbus_hello_registrar(env->buspath, ".example.a", - NULL, 0, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(conn_a == NULL); + ASSERT_ZERO(kdbus_hello_registrar(env->buspath, ".example.a", NULL, 0, KDBUS_HELLO_POLICY_HOLDER)); + ASSERT_ZERO(kdbus_hello_registrar(env->buspath, "example", NULL, 0, KDBUS_HELLO_POLICY_HOLDER)); - conn_a = kdbus_hello_registrar(env->buspath, "example", - NULL, 0, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(conn_a == NULL); - - conn_a = kdbus_hello_registrar(env->buspath, "com.example.a", - NULL, 0, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(conn_a); - - conn_b = kdbus_hello_registrar(env->buspath, "com.example.b", - NULL, 0, KDBUS_HELLO_POLICY_HOLDER); - ASSERT_RETURN(conn_b); + ASSERT_NONZERO(conn_a = kdbus_hello_registrar(env->buspath, "com.example.a", NULL, 0, KDBUS_HELLO_POLICY_HOLDER)); + ASSERT_NONZERO(conn_b = kdbus_hello_registrar(env->buspath, "com.example.b", NULL, 0, KDBUS_HELLO_POLICY_HOLDER)); /* * Verify there cannot be any duplicate entries, except for specific vs. @@ -45,33 +34,24 @@ int kdbus_test_policy(struct kdbus_test_env *env) .access = KDBUS_POLICY_SEE, }; - ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1)); - ret = kdbus_conn_update_policy(conn_b, "com.example.a", &access, 1); - ASSERT_RETURN(ret == -EEXIST); + ASSERT_RETURN(-EEXIST,==,kdbus_conn_update_policy(conn_b, "com.example.a", &access, 1)); - ret = kdbus_conn_update_policy(conn_b, "com.example.a.*", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_b, "com.example.a.*", &access, 1)); - ret = kdbus_conn_update_policy(conn_a, "com.example.a.*", &access, 1); - ASSERT_RETURN(ret == -EEXIST); + ASSERT_RETURN(-EEXIST,==,kdbus_conn_update_policy(conn_a, "com.example.a.*", &access, 1)); - ret = kdbus_conn_update_policy(conn_a, "com.example.*", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_a, "com.example.*", &access, 1)); - ret = kdbus_conn_update_policy(conn_b, "com.example.a", &access, 1); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_conn_update_policy(conn_b, "com.example.a", &access, 1)); - ret = kdbus_conn_update_policy(conn_b, "com.example.*", &access, 1); - ASSERT_RETURN(ret == -EEXIST); + ASSERT_RETURN(-EEXIST,==,kdbus_conn_update_policy(conn_b, "com.example.*", &access, 1)); /* Invalid name */ - ret = kdbus_conn_update_policy(conn_b, ".example.*", &access, 1); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_conn_update_policy(conn_b, ".example.*", &access, 1)); - ret = kdbus_conn_update_policy(conn_b, "example", &access, 1); - ASSERT_RETURN(ret == -EINVAL); + ASSERT_RETURN(-EINVAL,==,kdbus_conn_update_policy(conn_b, "example", &access, 1)); kdbus_conn_free(conn_b); kdbus_conn_free(conn_a); diff --git a/tools/testing/selftests/kdbus/test-send.c b/tools/testing/selftests/kdbus/test-send.c deleted file mode 100644 index 9bd8c8f..0000000 --- a/tools/testing/selftests/kdbus/test-send.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include -#include -#include -/* Use in conjunction with test-kdbus-daemon */ - -#include -#include -#include -#include -#include -#include -#include - -#include "kdbus-test.h" -#include "kdbus-util.h" -#include "kdbus-enum.h" - -int get_file(const char *fname, int flags, const char *content) -{ - FILE *f; - - if (access(fname, F_OK) < 0) { - f = fopen(fname, "w"); - if (!f) - return -1; - fprintf(f, "%s\n", content); - fclose(f); - } - - return open(fname, flags); -} - -int kdbus_test_send(struct kdbus_test_env *env) -{ - int ret; - int serial = 1; - int fds[3]; - size_t i; - - if (!env->conn) - return EXIT_FAILURE; - - fds[0] = get_file("/tmp/kdbus-test-send.rd", O_RDONLY, "foo"); - fds[1] = get_file("/tmp/kdbus-test-send.wr", O_WRONLY, "bar"); - fds[2] = get_file("/tmp/kdbus-test-send.rdwr", O_RDWR, "baz"); - - for (i = 0; i < ELEMENTSOF(fds); i++) { - if (fds[i] < 0) { - fprintf(stderr, "Unable to open data/fileN file(s)\n"); - return EXIT_FAILURE; - } - } - - ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++, - 0, 0, 0, 0, 0, NULL); - if (ret < 0) - fprintf(stderr, "error sending simple message: %d (%m)\n", - ret); - - ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++, - 0, 0, 0, 0, 1, fds); - if (ret < 0) - fprintf(stderr, "error sending message with 1 fd: %d (%m)\n", - ret); - - ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++, - 0, 0, 0, 0, 2, fds); - if (ret < 0) - fprintf(stderr, "error sending message with 2 fds: %d (%m)\n", - ret); - - ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++, - 0, 0, 0, 0, 3, fds); - if (ret < 0) - fprintf(stderr, "error sending message with 3 fds: %d (%m)\n", - ret); - - for (i = 0; i < ELEMENTSOF(fds); i++) - close(fds[i]); - - return EXIT_SUCCESS; -} diff --git a/tools/testing/selftests/kdbus/test-sync.c b/tools/testing/selftests/kdbus/test-sync.c index 77c3c41..3e7212c 100644 --- a/tools/testing/selftests/kdbus/test-sync.c +++ b/tools/testing/selftests/kdbus/test-sync.c @@ -22,7 +22,7 @@ static struct kdbus_conn *conn_a, *conn_b; static unsigned int cookie = 0xdeadbeef; -static void nop_handler(int sig) {} +static void nop_handler(int sig) { UNUSED(sig); } static int interrupt_sync(struct kdbus_conn *conn_src, struct kdbus_conn *conn_dst) @@ -37,36 +37,31 @@ static int interrupt_sync(struct kdbus_conn *conn_src, cookie++; pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, pid); + ASSERT_RETURN_VAL(pid,>=,0, pid); if (pid == 0) { - ret = sigaction(SIGINT, &sa, NULL); - ASSERT_EXIT(ret == 0); + ASSERT_EXIT_ZERO(sigaction(SIGINT, &sa, NULL)); - ret = kdbus_msg_send_sync(conn_dst, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - 100000000ULL, 0, conn_src->id, -1); - ASSERT_EXIT(ret == -ETIMEDOUT); + ASSERT_EXIT(-ETIMEDOUT,==,kdbus_msg_send_sync(conn_dst, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, 100000000ULL, 0, conn_src->id, -1)); - _exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } - ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL); - ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv_poll(conn_src, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); ret = kill(pid, SIGINT); - ASSERT_RETURN_VAL(ret == 0, ret); + ASSERT_RETURN_VAL(ret,==,0, ret); ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); if (WIFSIGNALED(status)) return TEST_ERR; - ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL); - ASSERT_RETURN(ret == -ETIMEDOUT); + ASSERT_RETURN(-ETIMEDOUT,==,kdbus_msg_recv_poll(conn_src, 100, NULL, NULL)); return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR; } @@ -79,18 +74,15 @@ static int close_epipe_sync(const char *bus) struct kdbus_conn *conn_dst; struct kdbus_msg *msg = NULL; - conn_src = kdbus_hello(bus, 0, NULL, 0); - ASSERT_RETURN(conn_src); + ASSERT_NONZERO(conn_src = kdbus_hello(bus, 0, NULL, 0)); - ret = kdbus_add_match_empty(conn_src); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_add_match_empty(conn_src)); - conn_dst = kdbus_hello(bus, 0, NULL, 0); - ASSERT_RETURN(conn_dst); + ASSERT_NONZERO(conn_dst = kdbus_hello(bus, 0, NULL, 0)); cookie++; pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, pid); + ASSERT_RETURN_VAL(pid,>=,0, pid); if (pid == 0) { uint64_t dst_id; @@ -99,26 +91,24 @@ static int close_epipe_sync(const char *bus) dst_id = conn_dst->id; kdbus_conn_free(conn_dst); - ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL); - ASSERT_EXIT(ret == 0 && msg->cookie == cookie); - ASSERT_EXIT(msg->src_id == dst_id); + ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(conn_src, -1, &msg, NULL)); + ASSERT_EXIT(msg->cookie,==,cookie); + ASSERT_EXIT(msg->src_id,==,dst_id); cookie++; - ret = kdbus_msg_send_sync(conn_src, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - 100000000ULL, 0, dst_id, -1); - ASSERT_EXIT(ret == -EPIPE); + /* it seems this test is inherently racy - EPIPE and ECONNRESET are pretty much indistinguishable - we should probably check for either of them */ + ret = kdbus_msg_send_sync(conn_src, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, 5000000000000ULL, 0, dst_id, -1); + if (-EPIPE != ret) + ASSERT_EXIT(-ECONNRESET,==,ret); /* need big timeout because we're not synchronized wrt dst_id closing */ - _exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } - ret = kdbus_msg_send(conn_dst, NULL, cookie, 0, 0, 0, - KDBUS_DST_ID_BROADCAST, 0, NULL); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(kdbus_msg_send(conn_dst, NULL, cookie, 0, 0, 0, KDBUS_DST_ID_BROADCAST)); cookie++; - ret = kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL); - ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv_poll(conn_dst, -1, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); @@ -127,7 +117,7 @@ static int close_epipe_sync(const char *bus) kdbus_conn_free(conn_src); ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); if (!WIFEXITED(status)) return TEST_ERR; @@ -145,32 +135,26 @@ static int cancel_fd_sync(struct kdbus_conn *conn_src, struct kdbus_msg *msg = NULL; cancel_fd = eventfd(0, 0); - ASSERT_RETURN_VAL(cancel_fd >= 0, cancel_fd); + ASSERT_RETURN_VAL(cancel_fd,>=,0, cancel_fd); cookie++; pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, pid); + ASSERT_RETURN_VAL(pid,>=,0, pid); if (pid == 0) { - ret = kdbus_msg_send_sync(conn_dst, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - 100000000ULL, 0, conn_src->id, - cancel_fd); - ASSERT_EXIT(ret == -ECANCELED); - - _exit(EXIT_SUCCESS); + ASSERT_EXIT(-ECANCELED,==,kdbus_msg_send_sync(conn_dst, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, 500000000000ULL, 0, conn_src->id, cancel_fd)); + exit(EXIT_SUCCESS); } - ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL); - ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + ASSERT_ZERO(kdbus_msg_recv_poll(conn_src, 100, &msg, NULL)); + ASSERT_RETURN(msg->cookie,==,cookie); kdbus_msg_free(msg); - ret = write(cancel_fd, &counter, sizeof(counter)); - ASSERT_RETURN(ret == sizeof(counter)); + ASSERT_RETURN((int)sizeof(counter),==,write(cancel_fd, &counter, sizeof(counter))); ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); if (WIFSIGNALED(status)) return TEST_ERR; @@ -189,32 +173,28 @@ static int no_cancel_sync(struct kdbus_conn *conn_src, /* pass eventfd, but never signal it so it shouldn't have any effect */ cancel_fd = eventfd(0, 0); - ASSERT_RETURN_VAL(cancel_fd >= 0, cancel_fd); + ASSERT_RETURN_VAL(cancel_fd,>=,0, cancel_fd); cookie++; pid = fork(); - ASSERT_RETURN_VAL(pid >= 0, pid); + ASSERT_RETURN_VAL(pid,>=,0, pid); if (pid == 0) { - ret = kdbus_msg_send_sync(conn_dst, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - 100000000ULL, 0, conn_src->id, - cancel_fd); - ASSERT_EXIT(ret == 0); - - _exit(EXIT_SUCCESS); + ASSERT_EXIT_ZERO(kdbus_msg_send_sync(conn_dst, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, 500000000000ULL, 0, conn_src->id, cancel_fd)); + exit(EXIT_SUCCESS); } ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL); - ASSERT_RETURN_VAL(ret == 0 && msg->cookie == cookie, -1); + ASSERT_RETURN_VAL(ret,==,0, -1); + ASSERT_RETURN_VAL(msg->cookie,==,cookie, -1); kdbus_msg_free(msg); ret = kdbus_msg_send_reply(conn_src, cookie, conn_dst->id); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); ret = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(ret >= 0, ret); + ASSERT_RETURN_VAL(ret,>=,0, ret); if (WIFSIGNALED(status)) return -1; @@ -224,24 +204,22 @@ static int no_cancel_sync(struct kdbus_conn *conn_src, static void *run_thread_reply(void *data) { - int ret; unsigned long status = TEST_OK; + UNUSED(data); - ret = kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL); - if (ret < 0) + if (0 > kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL)) goto exit_thread; kdbus_printf("Thread received message, sending reply ...\n"); - /* using an unknown cookie must fail */ - ret = kdbus_msg_send_reply(conn_a, ~cookie, conn_b->id); - if (ret != -EPERM) { + /* using an unknown cookie must fail iff not TIZEN */ + if (ONTIZEN(0,-EBADSLT) != kdbus_msg_send_reply(conn_a, ~cookie, conn_b->id)) + { status = TEST_ERR; goto exit_thread; } - ret = kdbus_msg_send_reply(conn_a, cookie, conn_b->id); - if (ret != 0) { + if (kdbus_msg_send_reply(conn_a, cookie, conn_b->id)) { status = TEST_ERR; goto exit_thread; } @@ -257,31 +235,23 @@ int kdbus_test_sync_reply(struct kdbus_test_env *env) pthread_t thread; int ret; - conn_a = kdbus_hello(env->buspath, 0, NULL, 0); - conn_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_a && conn_b); + ASSERT_NONZERO(conn_a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(conn_b = kdbus_hello(env->buspath, 0, NULL, 0)); pthread_create(&thread, NULL, run_thread_reply, NULL); ret = kdbus_msg_send_sync(conn_b, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, - 5000000000ULL, 0, conn_a->id, -1); + KDBUS_TIMEOUT_INFINITE, 0, conn_a->id, -1); pthread_join(thread, (void *) &status); - ASSERT_RETURN(status == 0); - ASSERT_RETURN(ret == 0); - - ret = interrupt_sync(conn_a, conn_b); - ASSERT_RETURN(ret == 0); - - ret = close_epipe_sync(env->buspath); - ASSERT_RETURN(ret == 0); - - ret = cancel_fd_sync(conn_a, conn_b); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(status); + ASSERT_ZERO(ret); - ret = no_cancel_sync(conn_a, conn_b); - ASSERT_RETURN(ret == 0); + ASSERT_ZERO(interrupt_sync(conn_a, conn_b)); + ASSERT_ZERO(close_epipe_sync(env->buspath)); + ASSERT_ZERO(cancel_fd_sync(conn_a, conn_b)); + ASSERT_ZERO(no_cancel_sync(conn_a, conn_b)); kdbus_printf("-- closing bus connections\n"); @@ -297,16 +267,13 @@ int kdbus_test_sync_reply(struct kdbus_test_env *env) static void *run_thread_byebye(void *data) { struct kdbus_cmd cmd_byebye = { .size = sizeof(cmd_byebye) }; - int ret; - ret = kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL); - if (ret == 0) { + if (0 == kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL)) { kdbus_printf("Thread received message, invoking BYEBYE ...\n"); - kdbus_msg_recv(conn_a, NULL, NULL); if (data == BYEBYE_ME) - kdbus_cmd_byebye(conn_b->fd, &cmd_byebye); + ASSERT_EXIT_ZERO(kdbus_cmd_byebye(conn_b->fd, &cmd_byebye)); else if (data == BYEBYE_THEM) - kdbus_cmd_byebye(conn_a->fd, &cmd_byebye); + ASSERT_EXIT_ZERO(kdbus_cmd_byebye(conn_a->fd, &cmd_byebye)); } pthread_exit(NULL); @@ -316,7 +283,6 @@ static void *run_thread_byebye(void *data) int kdbus_test_sync_byebye(struct kdbus_test_env *env) { pthread_t thread; - int ret; /* * This sends a synchronous message to a thread, which waits until it @@ -331,34 +297,24 @@ int kdbus_test_sync_byebye(struct kdbus_test_env *env) * reply cannot be sent by a disconnected target. */ - conn_a = kdbus_hello(env->buspath, 0, NULL, 0); - conn_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_a && conn_b); + ASSERT_NONZERO(conn_a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(conn_b = kdbus_hello(env->buspath, 0, NULL, 0)); pthread_create(&thread, NULL, run_thread_byebye, BYEBYE_ME); - ret = kdbus_msg_send_sync(conn_b, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - 5000000000ULL, 0, conn_a->id, -1); - - ASSERT_RETURN(ret == -ECONNRESET); + ASSERT_RETURN(-ECONNRESET,==,kdbus_msg_send_sync(conn_b, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, 5000000000ULL, 0, conn_a->id, -1)); pthread_join(thread, NULL); kdbus_conn_free(conn_a); kdbus_conn_free(conn_b); - conn_a = kdbus_hello(env->buspath, 0, NULL, 0); - conn_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_a && conn_b); + ASSERT_NONZERO(conn_a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(conn_b = kdbus_hello(env->buspath, 0, NULL, 0)); pthread_create(&thread, NULL, run_thread_byebye, BYEBYE_THEM); - ret = kdbus_msg_send_sync(conn_b, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - 5000000000ULL, 0, conn_a->id, -1); - - ASSERT_RETURN(ret == -EPIPE); + ASSERT_RETURN(-EPIPE,==,kdbus_msg_send_sync(conn_b, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, 5000000000ULL, 0, conn_a->id, -1)); pthread_join(thread, NULL); diff --git a/tools/testing/selftests/kdbus/test-timeout.c b/tools/testing/selftests/kdbus/test-timeout.c index a5cdaf2..5e15dda 100644 --- a/tools/testing/selftests/kdbus/test-timeout.c +++ b/tools/testing/selftests/kdbus/test-timeout.c @@ -16,7 +16,7 @@ #include "kdbus-util.h" #include "kdbus-enum.h" -int timeout_msg_recv(struct kdbus_conn *conn, uint64_t *expected) +wur int timeout_msg_recv(struct kdbus_conn *conn, uint64_t type, uint64_t *cookie_reply, uint64_t *seqnum, uint64_t *monotonic_ns, uint64_t *realtime_ns) { struct kdbus_cmd_recv recv = { .size = sizeof(recv) }; struct kdbus_msg *msg; @@ -30,11 +30,35 @@ int timeout_msg_recv(struct kdbus_conn *conn, uint64_t *expected) msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset); - ASSERT_RETURN_VAL(msg->payload_type == KDBUS_PAYLOAD_KERNEL, -EINVAL); - ASSERT_RETURN_VAL(msg->src_id == KDBUS_SRC_ID_KERNEL, -EINVAL); - ASSERT_RETURN_VAL(msg->dst_id == conn->id, -EINVAL); + ASSERT_RETURN_VAL(msg->payload_type,==,(typeof(msg->payload_type))KDBUS_PAYLOAD_KERNEL, -EINVAL); + ASSERT_RETURN_VAL(msg->src_id,==,(typeof(msg->src_id))KDBUS_SRC_ID_KERNEL, -EINVAL); + ASSERT_RETURN_VAL(msg->dst_id,==,conn->id, -EINVAL); + + { + const struct kdbus_item *item; + bool have_type = false; + bool have_timestamp = false; + + KDBUS_ITEM_FOREACH(item, msg, items) { + if (item->type == type) { + ASSERT_ZERO(have_type); + have_type = true; + ASSERT_RETURN(item->size,==,2*sizeof(uint64_t)); + continue; + } + ASSERT_RETURN(item->type,==,(uint64_t)KDBUS_ITEM_TIMESTAMP); + ASSERT_ZERO(have_timestamp); + have_timestamp = true; + ASSERT_RETURN(item->size,==,2*sizeof(uint64_t) + sizeof(struct kdbus_timestamp)); + #define S(P) if (P) *P = item->timestamp.P; + S(seqnum) + S(monotonic_ns) + S(realtime_ns) + #undef S + } + } - *expected &= ~(1ULL << msg->cookie_reply); + *cookie_reply = msg->cookie_reply; kdbus_printf("Got message timeout for cookie %llu\n", msg->cookie_reply); @@ -45,7 +69,7 @@ int timeout_msg_recv(struct kdbus_conn *conn, uint64_t *expected) return 0; } -int kdbus_test_timeout(struct kdbus_test_env *env) +wur int kdbus_test_timeout(struct kdbus_test_env *env) { struct kdbus_conn *conn_a, *conn_b; struct pollfd fd; @@ -53,9 +77,8 @@ int kdbus_test_timeout(struct kdbus_test_env *env) uint64_t expected = 0; uint64_t cookie = 0xdeadbeef; - conn_a = kdbus_hello(env->buspath, 0, NULL, 0); - conn_b = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(conn_a && conn_b); + ASSERT_NONZERO(conn_a = kdbus_hello(env->buspath, 0, NULL, 0)); + ASSERT_NONZERO(conn_b = kdbus_hello(env->buspath, 0, NULL, 0)); fd.fd = conn_b->fd; @@ -66,14 +89,12 @@ int kdbus_test_timeout(struct kdbus_test_env *env) for (i = 0; i < n_msgs; i++, cookie++) { kdbus_printf("Sending message with cookie %llu ...\n", (unsigned long long)cookie); - ASSERT_RETURN(kdbus_msg_send(conn_b, NULL, cookie, - KDBUS_MSG_EXPECT_REPLY, - (i + 1) * 100ULL * 1000000ULL, 0, - conn_a->id, 0, NULL) == 0); + ASSERT_ZERO(kdbus_msg_send(conn_b, NULL, cookie, KDBUS_MSG_EXPECT_REPLY, (i + 1) * 100ULL * 1000000ULL, 0, conn_a->id)); expected |= 1ULL << cookie; } for (;;) { + uint64_t cookie_reply; fd.events = POLLIN | POLLPRI | POLLHUP; fd.revents = 0; @@ -84,13 +105,13 @@ int kdbus_test_timeout(struct kdbus_test_env *env) break; if (fd.revents & POLLIN) - ASSERT_RETURN(!timeout_msg_recv(conn_b, &expected)); + ASSERT_ZERO(timeout_msg_recv(conn_b, KDBUS_ITEM_REPLY_TIMEOUT, &cookie_reply, NULL, NULL, NULL)); - if (expected == 0) + if (!(expected &= ~(1ULL << cookie_reply))) break; } - ASSERT_RETURN(expected == 0); + ASSERT_ZERO(expected); kdbus_conn_free(conn_a); kdbus_conn_free(conn_b);