From 6d461a4fe7896faa1aec5a5417888cf179e46b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Fabian=20Silva=20Delgado?= Date: Mon, 22 Feb 2016 01:12:47 -0300 Subject: Linux-libre 4.4.2-gnu --- tools/testing/selftests/kdbus/.gitignore | 1 - tools/testing/selftests/kdbus/Makefile | 49 - tools/testing/selftests/kdbus/kdbus-enum.c | 94 -- tools/testing/selftests/kdbus/kdbus-enum.h | 15 - tools/testing/selftests/kdbus/kdbus-test.c | 905 ------------ tools/testing/selftests/kdbus/kdbus-test.h | 84 -- tools/testing/selftests/kdbus/kdbus-util.c | 1612 ---------------------- tools/testing/selftests/kdbus/kdbus-util.h | 218 --- tools/testing/selftests/kdbus/test-activator.c | 321 ----- tools/testing/selftests/kdbus/test-benchmark.c | 451 ------ tools/testing/selftests/kdbus/test-bus.c | 175 --- tools/testing/selftests/kdbus/test-chat.c | 124 -- tools/testing/selftests/kdbus/test-connection.c | 597 -------- tools/testing/selftests/kdbus/test-daemon.c | 65 - tools/testing/selftests/kdbus/test-endpoint.c | 352 ----- tools/testing/selftests/kdbus/test-fd.c | 789 ----------- tools/testing/selftests/kdbus/test-free.c | 64 - tools/testing/selftests/kdbus/test-match.c | 441 ------ tools/testing/selftests/kdbus/test-message.c | 736 ---------- tools/testing/selftests/kdbus/test-metadata-ns.c | 500 ------- tools/testing/selftests/kdbus/test-monitor.c | 176 --- tools/testing/selftests/kdbus/test-names.c | 272 ---- tools/testing/selftests/kdbus/test-policy-ns.c | 632 --------- tools/testing/selftests/kdbus/test-policy-priv.c | 1285 ----------------- tools/testing/selftests/kdbus/test-policy.c | 80 -- tools/testing/selftests/kdbus/test-sync.c | 369 ----- tools/testing/selftests/kdbus/test-timeout.c | 99 -- 27 files changed, 10506 deletions(-) delete mode 100644 tools/testing/selftests/kdbus/.gitignore delete mode 100644 tools/testing/selftests/kdbus/Makefile delete mode 100644 tools/testing/selftests/kdbus/kdbus-enum.c delete mode 100644 tools/testing/selftests/kdbus/kdbus-enum.h delete mode 100644 tools/testing/selftests/kdbus/kdbus-test.c delete mode 100644 tools/testing/selftests/kdbus/kdbus-test.h delete mode 100644 tools/testing/selftests/kdbus/kdbus-util.c delete mode 100644 tools/testing/selftests/kdbus/kdbus-util.h delete mode 100644 tools/testing/selftests/kdbus/test-activator.c delete mode 100644 tools/testing/selftests/kdbus/test-benchmark.c delete mode 100644 tools/testing/selftests/kdbus/test-bus.c delete mode 100644 tools/testing/selftests/kdbus/test-chat.c delete mode 100644 tools/testing/selftests/kdbus/test-connection.c delete mode 100644 tools/testing/selftests/kdbus/test-daemon.c delete mode 100644 tools/testing/selftests/kdbus/test-endpoint.c delete mode 100644 tools/testing/selftests/kdbus/test-fd.c delete mode 100644 tools/testing/selftests/kdbus/test-free.c delete mode 100644 tools/testing/selftests/kdbus/test-match.c delete mode 100644 tools/testing/selftests/kdbus/test-message.c delete mode 100644 tools/testing/selftests/kdbus/test-metadata-ns.c delete mode 100644 tools/testing/selftests/kdbus/test-monitor.c delete mode 100644 tools/testing/selftests/kdbus/test-names.c delete mode 100644 tools/testing/selftests/kdbus/test-policy-ns.c delete mode 100644 tools/testing/selftests/kdbus/test-policy-priv.c delete mode 100644 tools/testing/selftests/kdbus/test-policy.c delete mode 100644 tools/testing/selftests/kdbus/test-sync.c delete mode 100644 tools/testing/selftests/kdbus/test-timeout.c (limited to 'tools/testing/selftests/kdbus') diff --git a/tools/testing/selftests/kdbus/.gitignore b/tools/testing/selftests/kdbus/.gitignore deleted file mode 100644 index d3ef42f6a..000000000 --- a/tools/testing/selftests/kdbus/.gitignore +++ /dev/null @@ -1 +0,0 @@ -kdbus-test diff --git a/tools/testing/selftests/kdbus/Makefile b/tools/testing/selftests/kdbus/Makefile deleted file mode 100644 index 8f36cb566..000000000 --- a/tools/testing/selftests/kdbus/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -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 - -OBJS= \ - kdbus-enum.o \ - kdbus-util.o \ - kdbus-test.o \ - kdbus-test.o \ - test-activator.o \ - test-benchmark.o \ - test-bus.o \ - test-chat.o \ - test-connection.o \ - test-daemon.o \ - test-endpoint.o \ - test-fd.o \ - test-free.o \ - test-match.o \ - test-message.o \ - test-metadata-ns.o \ - test-monitor.o \ - test-names.o \ - test-policy.o \ - test-policy-ns.o \ - test-policy-priv.o \ - test-sync.o \ - test-timeout.o - -all: kdbus-test - -include ../lib.mk - -%.o: %.c kdbus-enum.h kdbus-test.h kdbus-util.h - $(CC) $(CFLAGS) -c $< -o $@ - -kdbus-test: $(OBJS) - $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@ - -TEST_PROGS := kdbus-test - -run_tests: - ./kdbus-test --tap - -clean: - rm -f *.o kdbus-test diff --git a/tools/testing/selftests/kdbus/kdbus-enum.c b/tools/testing/selftests/kdbus/kdbus-enum.c deleted file mode 100644 index 4f1e57978..000000000 --- a/tools/testing/selftests/kdbus/kdbus-enum.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2013-2015 Kay Sievers - * - * kdbus is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kdbus-util.h" -#include "kdbus-enum.h" - -struct kdbus_enum_table { - long long id; - const char *name; -}; - -#define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[] -#define ENUM(_id) { .id = _id, .name = STRINGIFY(_id) } -#define LOOKUP(what) \ - const char *enum_##what(long long id) \ - { \ - for (size_t i = 0; i < ELEMENTSOF(kdbus_table_##what); i++) \ - if (id == kdbus_table_##what[i].id) \ - return kdbus_table_##what[i].name; \ - return "UNKNOWN"; \ - } - -TABLE(CMD) = { - ENUM(KDBUS_CMD_BUS_MAKE), - ENUM(KDBUS_CMD_ENDPOINT_MAKE), - ENUM(KDBUS_CMD_HELLO), - ENUM(KDBUS_CMD_SEND), - ENUM(KDBUS_CMD_RECV), - ENUM(KDBUS_CMD_LIST), - ENUM(KDBUS_CMD_NAME_RELEASE), - ENUM(KDBUS_CMD_CONN_INFO), - ENUM(KDBUS_CMD_MATCH_ADD), - ENUM(KDBUS_CMD_MATCH_REMOVE), -}; -LOOKUP(CMD); - -TABLE(MSG) = { - ENUM(_KDBUS_ITEM_NULL), - ENUM(KDBUS_ITEM_PAYLOAD_VEC), - ENUM(KDBUS_ITEM_PAYLOAD_OFF), - ENUM(KDBUS_ITEM_PAYLOAD_MEMFD), - ENUM(KDBUS_ITEM_FDS), - ENUM(KDBUS_ITEM_BLOOM_PARAMETER), - ENUM(KDBUS_ITEM_BLOOM_FILTER), - ENUM(KDBUS_ITEM_DST_NAME), - ENUM(KDBUS_ITEM_MAKE_NAME), - ENUM(KDBUS_ITEM_ATTACH_FLAGS_SEND), - ENUM(KDBUS_ITEM_ATTACH_FLAGS_RECV), - ENUM(KDBUS_ITEM_ID), - ENUM(KDBUS_ITEM_NAME), - ENUM(KDBUS_ITEM_TIMESTAMP), - ENUM(KDBUS_ITEM_CREDS), - ENUM(KDBUS_ITEM_PIDS), - ENUM(KDBUS_ITEM_AUXGROUPS), - ENUM(KDBUS_ITEM_OWNED_NAME), - ENUM(KDBUS_ITEM_TID_COMM), - ENUM(KDBUS_ITEM_PID_COMM), - ENUM(KDBUS_ITEM_EXE), - ENUM(KDBUS_ITEM_CMDLINE), - ENUM(KDBUS_ITEM_CGROUP), - ENUM(KDBUS_ITEM_CAPS), - ENUM(KDBUS_ITEM_SECLABEL), - ENUM(KDBUS_ITEM_AUDIT), - ENUM(KDBUS_ITEM_CONN_DESCRIPTION), - ENUM(KDBUS_ITEM_NAME_ADD), - ENUM(KDBUS_ITEM_NAME_REMOVE), - ENUM(KDBUS_ITEM_NAME_CHANGE), - ENUM(KDBUS_ITEM_ID_ADD), - ENUM(KDBUS_ITEM_ID_REMOVE), - ENUM(KDBUS_ITEM_REPLY_TIMEOUT), - ENUM(KDBUS_ITEM_REPLY_DEAD), -}; -LOOKUP(MSG); - -TABLE(PAYLOAD) = { - ENUM(KDBUS_PAYLOAD_KERNEL), - ENUM(KDBUS_PAYLOAD_DBUS), -}; -LOOKUP(PAYLOAD); diff --git a/tools/testing/selftests/kdbus/kdbus-enum.h b/tools/testing/selftests/kdbus/kdbus-enum.h deleted file mode 100644 index ed28cca26..000000000 --- a/tools/testing/selftests/kdbus/kdbus-enum.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2013-2015 Kay Sievers - * - * kdbus is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * 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); -const char *enum_MSG(long long id); -const char *enum_MATCH(long long id); -const char *enum_PAYLOAD(long long id); diff --git a/tools/testing/selftests/kdbus/kdbus-test.c b/tools/testing/selftests/kdbus/kdbus-test.c deleted file mode 100644 index db5738157..000000000 --- a/tools/testing/selftests/kdbus/kdbus-test.c +++ /dev/null @@ -1,905 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kdbus-util.h" -#include "kdbus-enum.h" -#include "kdbus-test.h" - -enum { - TEST_CREATE_BUS = 1 << 0, - TEST_CREATE_CONN = 1 << 1, -}; - -struct kdbus_test { - const char *name; - const char *desc; - int (*func)(struct kdbus_test_env *env); - unsigned int flags; -}; - -struct kdbus_test_args { - bool mntns; - bool pidns; - bool userns; - char *uid_map; - char *gid_map; - int loop; - int wait; - int fork; - int tap_output; - char *module; - char *root; - char *test; - char *busname; -}; - -static const struct kdbus_test tests[] = { - { - .name = "bus-make", - .desc = "bus make functions", - .func = kdbus_test_bus_make, - .flags = 0, - }, - { - .name = "hello", - .desc = "the HELLO command", - .func = kdbus_test_hello, - .flags = TEST_CREATE_BUS, - }, - { - .name = "byebye", - .desc = "the BYEBYE command", - .func = kdbus_test_byebye, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "chat", - .desc = "a chat pattern", - .func = kdbus_test_chat, - .flags = TEST_CREATE_BUS, - }, - { - .name = "daemon", - .desc = "a simple daemon", - .func = kdbus_test_daemon, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "fd-passing", - .desc = "file descriptor passing", - .func = kdbus_test_fd_passing, - .flags = TEST_CREATE_BUS, - }, - { - .name = "endpoint", - .desc = "custom endpoint", - .func = kdbus_test_custom_endpoint, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "monitor", - .desc = "monitor functionality", - .func = kdbus_test_monitor, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "name-basics", - .desc = "basic name registry functions", - .func = kdbus_test_name_basic, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "name-conflict", - .desc = "name registry conflict details", - .func = kdbus_test_name_conflict, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "name-queue", - .desc = "queuing of names", - .func = kdbus_test_name_queue, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "name-takeover", - .desc = "takeover of names", - .func = kdbus_test_name_takeover, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "message-basic", - .desc = "basic message handling", - .func = kdbus_test_message_basic, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "message-prio", - .desc = "handling of messages with priority", - .func = kdbus_test_message_prio, - .flags = TEST_CREATE_BUS, - }, - { - .name = "message-quota", - .desc = "message quotas are enforced", - .func = kdbus_test_message_quota, - .flags = TEST_CREATE_BUS, - }, - { - .name = "memory-access", - .desc = "memory access", - .func = kdbus_test_memory_access, - .flags = TEST_CREATE_BUS, - }, - { - .name = "timeout", - .desc = "timeout", - .func = kdbus_test_timeout, - .flags = TEST_CREATE_BUS, - }, - { - .name = "sync-byebye", - .desc = "synchronous replies vs. BYEBYE", - .func = kdbus_test_sync_byebye, - .flags = TEST_CREATE_BUS, - }, - { - .name = "sync-reply", - .desc = "synchronous replies", - .func = kdbus_test_sync_reply, - .flags = TEST_CREATE_BUS, - }, - { - .name = "message-free", - .desc = "freeing of memory", - .func = kdbus_test_free, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "connection-info", - .desc = "retrieving connection information", - .func = kdbus_test_conn_info, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "connection-update", - .desc = "updating connection information", - .func = kdbus_test_conn_update, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "writable-pool", - .desc = "verifying pools are never writable", - .func = kdbus_test_writable_pool, - .flags = TEST_CREATE_BUS, - }, - { - .name = "policy", - .desc = "policy", - .func = kdbus_test_policy, - .flags = TEST_CREATE_BUS, - }, - { - .name = "policy-priv", - .desc = "unprivileged bus access", - .func = kdbus_test_policy_priv, - .flags = TEST_CREATE_BUS, - }, - { - .name = "policy-ns", - .desc = "policy in user namespaces", - .func = kdbus_test_policy_ns, - .flags = TEST_CREATE_BUS, - }, - { - .name = "metadata-ns", - .desc = "metadata in different namespaces", - .func = kdbus_test_metadata_ns, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "match-id-add", - .desc = "adding of matches by id", - .func = kdbus_test_match_id_add, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "match-id-remove", - .desc = "removing of matches by id", - .func = kdbus_test_match_id_remove, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "match-replace", - .desc = "replace of matches with the same cookie", - .func = kdbus_test_match_replace, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "match-name-add", - .desc = "adding of matches by name", - .func = kdbus_test_match_name_add, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "match-name-remove", - .desc = "removing of matches by name", - .func = kdbus_test_match_name_remove, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "match-name-change", - .desc = "matching for name changes", - .func = kdbus_test_match_name_change, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "match-bloom", - .desc = "matching with bloom filters", - .func = kdbus_test_match_bloom, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "activator", - .desc = "activator connections", - .func = kdbus_test_activator, - .flags = TEST_CREATE_BUS | TEST_CREATE_CONN, - }, - { - .name = "benchmark", - .desc = "benchmark", - .func = kdbus_test_benchmark, - .flags = TEST_CREATE_BUS, - }, - { - .name = "benchmark-nomemfds", - .desc = "benchmark without using memfds", - .func = kdbus_test_benchmark_nomemfds, - .flags = TEST_CREATE_BUS, - }, - { - .name = "benchmark-uds", - .desc = "benchmark comparison to UDS", - .func = kdbus_test_benchmark_uds, - .flags = TEST_CREATE_BUS, - }, -}; - -#define N_TESTS ((int) (sizeof(tests) / sizeof(tests[0]))) - -static int test_prepare_env(const struct kdbus_test *t, - const struct kdbus_test_args *args, - struct kdbus_test_env *env) -{ - if (t->flags & TEST_CREATE_BUS) { - char *s; - char *n = NULL; - int ret; - - asprintf(&s, "%s/control", args->root); - - env->control_fd = open(s, O_RDWR); - free(s); - ASSERT_RETURN(env->control_fd >= 0); - - if (!args->busname) { - n = unique_name("test-bus"); - ASSERT_RETURN(n); - } - - ret = kdbus_create_bus(env->control_fd, - args->busname ?: n, - _KDBUS_ATTACH_ALL, &s); - free(n); - ASSERT_RETURN(ret == 0); - - asprintf(&env->buspath, "%s/%s/bus", args->root, s); - free(s); - } - - if (t->flags & TEST_CREATE_CONN) { - env->conn = kdbus_hello(env->buspath, 0, NULL, 0); - ASSERT_RETURN(env->conn); - } - - env->root = args->root; - env->module = args->module; - - return 0; -} - -void test_unprepare_env(const struct kdbus_test *t, struct kdbus_test_env *env) -{ - if (env->conn) { - kdbus_conn_free(env->conn); - env->conn = NULL; - } - - if (env->control_fd >= 0) { - close(env->control_fd); - env->control_fd = -1; - } - - if (env->buspath) { - free(env->buspath); - env->buspath = NULL; - } -} - -static int test_run(const struct kdbus_test *t, - const struct kdbus_test_args *kdbus_args, - int wait) -{ - int ret; - struct kdbus_test_env env = {}; - - ret = test_prepare_env(t, kdbus_args, &env); - if (ret != TEST_OK) - return ret; - - if (wait > 0) { - printf("Sleeping %d seconds before running test ...\n", wait); - sleep(wait); - } - - ret = t->func(&env); - test_unprepare_env(t, &env); - return ret; -} - -static int test_run_forked(const struct kdbus_test *t, - const struct kdbus_test_args *kdbus_args, - int wait) -{ - int ret; - pid_t pid; - - pid = fork(); - if (pid < 0) { - return TEST_ERR; - } else if (pid == 0) { - 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); -} - -static void print_test_result(int ret) -{ - switch (ret) { - case TEST_OK: - printf("OK"); - break; - case TEST_SKIP: - printf("SKIPPED"); - break; - case TEST_ERR: - printf("ERROR"); - break; - } -} - -static int start_all_tests(struct kdbus_test_args *kdbus_args) -{ - int ret; - unsigned int fail_cnt = 0; - unsigned int skip_cnt = 0; - unsigned int ok_cnt = 0; - unsigned int i; - - if (kdbus_args->tap_output) { - printf("1..%d\n", N_TESTS); - fflush(stdout); - } - - kdbus_util_verbose = false; - - for (i = 0; i < N_TESTS; i++) { - const struct kdbus_test *t = tests + i; - - if (!kdbus_args->tap_output) { - unsigned int n; - - printf("Testing %s (%s) ", t->desc, t->name); - for (n = 0; n < 60 - strlen(t->desc) - strlen(t->name); n++) - printf("."); - printf(" "); - } - - ret = test_run_forked(t, kdbus_args, 0); - switch (ret) { - case TEST_OK: - ok_cnt++; - break; - case TEST_SKIP: - skip_cnt++; - break; - case TEST_ERR: - fail_cnt++; - break; - } - - if (kdbus_args->tap_output) { - printf("%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"); - } - } - - if (kdbus_args->tap_output) - printf("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", - 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) -{ - int i, ret; - bool test_found = false; - - 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; - } - - return TEST_OK; -} - -static void usage(const char *argv0) -{ - unsigned int i, j; - - printf("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-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" - "\t --mntns New mount namespace\n" - "\t --pidns New PID namespace\n" - "\t --userns New user namespace\n" - "\t --uidmap uid_map UID map for user namespace\n" - "\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" - "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); - - for (j = 0; j < 24 - strlen(t->name); j++) - printf(" "); - - printf("Test %s\n", t->desc); - } - - printf("\n"); - printf("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) -{ - if (args->userns || args->pidns || args->mntns) - printf("# 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"); -} - -void print_metadata_support(void) -{ - bool no_meta_audit, no_meta_cgroups, no_meta_seclabel; - - /* - * KDBUS_ATTACH_CGROUP, KDBUS_ATTACH_AUDIT and - * KDBUS_ATTACH_SECLABEL - */ - no_meta_audit = !config_auditsyscall_is_enabled(); - no_meta_cgroups = !config_cgroups_is_enabled(); - 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", - no_meta_audit ? "AUDIT " : "", - no_meta_cgroups ? "CGROUP " : "", - no_meta_seclabel ? "SECLABEL " : ""); - else - printf("# Starting tests with full metadata support\n"); -} - -int run_tests(struct kdbus_test_args *kdbus_args) -{ - int ret; - static char control[4096]; - - snprintf(control, sizeof(control), "%s/control", kdbus_args->root); - - if (access(control, W_OK) < 0) { - printf("Unable to locate control node at '%s'.\n", - control); - return TEST_ERR; - } - - if (kdbus_args->test) { - ret = start_one_test(kdbus_args); - } else { - do { - ret = start_all_tests(kdbus_args); - if (ret != TEST_OK) - break; - } while (kdbus_args->loop); - } - - return ret; -} - -static void nop_handler(int sig) {} - -static int test_prepare_mounts(struct kdbus_test_args *kdbus_args) -{ - int ret; - char kdbusfs[64] = {'\0'}; - - snprintf(kdbusfs, sizeof(kdbusfs), "%sfs", kdbus_args->module); - - /* make current mount slave */ - ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL); - if (ret < 0) { - ret = -errno; - printf("error mount() root: %d (%m)\n", ret); - return ret; - } - - /* Remount procfs since we need it in our tests */ - if (kdbus_args->pidns) { - ret = mount("proc", "/proc", "proc", - MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL); - if (ret < 0) { - ret = -errno; - printf("error mount() /proc : %d (%m)\n", ret); - return ret; - } - } - - /* Remount kdbusfs */ - ret = mount(kdbusfs, kdbus_args->root, kdbusfs, - MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL); - if (ret < 0) { - ret = -errno; - printf("error mount() %s :%d (%m)\n", kdbusfs, ret); - return ret; - } - - return 0; -} - -int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args) -{ - int ret; - int efd = -1; - int status; - pid_t pid, rpid; - struct sigaction oldsa; - struct sigaction sa = { - .sa_handler = nop_handler, - .sa_flags = SA_NOCLDSTOP, - }; - - efd = eventfd(0, EFD_CLOEXEC); - if (efd < 0) { - ret = -errno; - printf("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); - return TEST_ERR; - } - - /* setup namespaces */ - pid = syscall(__NR_clone, SIGCHLD| - (kdbus_args->userns ? CLONE_NEWUSER : 0) | - (kdbus_args->mntns ? CLONE_NEWNS : 0) | - (kdbus_args->pidns ? CLONE_NEWPID : 0), NULL); - if (pid < 0) { - printf("clone() failed: %d (%m)\n", -errno); - return TEST_ERR; - } - - if (pid == 0) { - eventfd_t event_status = 0; - - ret = prctl(PR_SET_PDEATHSIG, SIGKILL); - if (ret < 0) { - ret = -errno; - printf("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); - } - - ret = eventfd_read(efd, &event_status); - if (ret < 0 || event_status != 1) { - printf("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); - } - } - - ret = run_tests(kdbus_args); - _exit(ret); - } - - /* Setup userns mapping */ - if (kdbus_args->userns) { - 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"); - eventfd_write(efd, 2); - return TEST_ERR; - } - } - - ret = eventfd_write(efd, 1); - if (ret < 0) { - ret = -errno; - printf("error eventfd_write(): %d (%m)\n", ret); - return TEST_ERR; - } - - rpid = waitpid(pid, &status, 0); - ASSERT_RETURN_VAL(rpid == pid, TEST_ERR); - - close(efd); - - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - return TEST_ERR; - - return TEST_OK; -} - -int start_tests(struct kdbus_test_args *kdbus_args) -{ - int ret; - bool namespaces; - static char fspath[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"); - return TEST_ERR; - } - - if (kdbus_args->userns) { - if (!config_user_ns_is_enabled()) { - printf("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"); - return TEST_ERR; - } - } - - 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; - } - - /* Start tests */ - if (namespaces) - ret = run_tests_in_namespaces(kdbus_args); - else - ret = run_tests(kdbus_args); - - return ret; -} - -int main(int argc, char *argv[]) -{ - int t, ret = 0; - struct kdbus_test_args *kdbus_args; - enum { - ARG_MNTNS = 0x100, - ARG_PIDNS, - ARG_USERNS, - ARG_UIDMAP, - ARG_GIDMAP, - }; - - 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)); - - 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' }, - { "bus", required_argument, NULL, 'b' }, - { "wait", required_argument, NULL, 'w' }, - { "fork", no_argument, NULL, 'f' }, - { "module", required_argument, NULL, 'm' }, - { "tap", no_argument, NULL, 'a' }, - { "mntns", no_argument, NULL, ARG_MNTNS }, - { "pidns", no_argument, NULL, ARG_PIDNS }, - { "userns", no_argument, NULL, ARG_USERNS }, - { "uidmap", required_argument, NULL, ARG_UIDMAP }, - { "gidmap", required_argument, NULL, ARG_GIDMAP }, - {} - }; - - srand(time(NULL)); - - while ((t = getopt_long(argc, argv, "hxfm:r:t:b:w:a", options, NULL)) >= 0) { - switch (t) { - case 'x': - kdbus_args->loop = 1; - break; - - case 'm': - kdbus_args->module = optarg; - break; - - case 'r': - kdbus_args->root = optarg; - break; - - case 't': - kdbus_args->test = optarg; - break; - - case 'b': - kdbus_args->busname = optarg; - break; - - case 'w': - kdbus_args->wait = strtol(optarg, NULL, 10); - break; - - case 'f': - kdbus_args->fork = 1; - break; - - case 'a': - kdbus_args->tap_output = 1; - break; - - case ARG_MNTNS: - kdbus_args->mntns = true; - break; - - case ARG_PIDNS: - kdbus_args->pidns = true; - break; - - case ARG_USERNS: - kdbus_args->userns = true; - break; - - case ARG_UIDMAP: - kdbus_args->uid_map = optarg; - break; - - case ARG_GIDMAP: - kdbus_args->gid_map = optarg; - break; - - default: - case 'h': - usage(argv[0]); - } - } - - 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 deleted file mode 100644 index ee937f9a8..000000000 --- a/tools/testing/selftests/kdbus/kdbus-test.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _TEST_KDBUS_H_ -#define _TEST_KDBUS_H_ - -struct kdbus_test_env { - char *buspath; - const char *root; - const char *module; - int control_fd; - struct kdbus_conn *conn; -}; - -enum { - TEST_OK, - TEST_SKIP, - TEST_ERR, -}; - -#define ASSERT_RETURN_VAL(cond, val) \ - if (!(cond)) { \ - fprintf(stderr, "Assertion '%s' failed in %s(), %s:%d\n", \ - #cond, __func__, __FILE__, __LINE__); \ - return val; \ - } - -#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_BREAK(cond) \ - if (!(cond)) { \ - fprintf(stderr, "Assertion '%s' failed in %s(), %s:%d\n", \ - #cond, __func__, __FILE__, __LINE__); \ - break; \ - } - -#define ASSERT_RETURN(cond) \ - ASSERT_RETURN_VAL(cond, TEST_ERR) - -#define ASSERT_EXIT(cond) \ - ASSERT_EXIT_VAL(cond, EXIT_FAILURE) - -int kdbus_test_activator(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_name_takeover(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_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); - -#endif /* _TEST_KDBUS_H_ */ diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c deleted file mode 100644 index 82fa89b1a..000000000 --- a/tools/testing/selftests/kdbus/kdbus-util.c +++ /dev/null @@ -1,1612 +0,0 @@ -/* - * Copyright (C) 2013-2015 Daniel Mack - * Copyright (C) 2013-2015 Kay Sievers - * Copyright (C) 2014-2015 Djalal Harouni - * - * kdbus is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __NR_memfd_create - #ifdef __x86_64__ - #define __NR_memfd_create 319 - #elif defined __arm__ - #define __NR_memfd_create 385 - #else - #define __NR_memfd_create 356 - #endif -#endif - -#include "kdbus-api.h" -#include "kdbus-util.h" -#include "kdbus-enum.h" - -#ifndef F_ADD_SEALS -#define F_LINUX_SPECIFIC_BASE 1024 -#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) -#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) - -#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */ -#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */ -#define F_SEAL_GROW 0x0004 /* prevent file from growing */ -#define F_SEAL_WRITE 0x0008 /* prevent writes */ -#endif - -int kdbus_util_verbose = true; - -int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask) -{ - int ret; - FILE *file; - unsigned long long value; - - file = fopen(path, "r"); - if (!file) { - ret = -errno; - kdbus_printf("--- error fopen(): %d (%m)\n", ret); - return ret; - } - - ret = fscanf(file, "%llu", &value); - if (ret != 1) { - if (ferror(file)) - ret = -errno; - else - ret = -EIO; - - kdbus_printf("--- error fscanf(): %d\n", ret); - fclose(file); - return ret; - } - - *mask = (uint64_t)value; - - fclose(file); - - return 0; -} - -int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask) -{ - int ret; - FILE *file; - - file = fopen(path, "w"); - if (!file) { - ret = -errno; - kdbus_printf("--- error open(): %d (%m)\n", ret); - return ret; - } - - ret = fprintf(file, "%llu", (unsigned long long)mask); - if (ret <= 0) { - ret = -EIO; - kdbus_printf("--- error fprintf(): %d\n", ret); - } - - fclose(file); - - return ret > 0 ? 0 : ret; -} - -int kdbus_create_bus(int control_fd, const char *name, - uint64_t owner_meta, char **path) -{ - struct { - struct kdbus_cmd cmd; - - /* bloom size item */ - struct { - uint64_t size; - uint64_t type; - struct kdbus_bloom_parameter bloom; - } bp; - - /* owner metadata items */ - struct { - uint64_t size; - uint64_t type; - uint64_t flags; - } attach; - - /* name item */ - struct { - uint64_t size; - uint64_t type; - char str[64]; - } name; - } bus_make; - int ret; - - memset(&bus_make, 0, sizeof(bus_make)); - bus_make.bp.size = sizeof(bus_make.bp); - bus_make.bp.type = KDBUS_ITEM_BLOOM_PARAMETER; - bus_make.bp.bloom.size = 64; - bus_make.bp.bloom.n_hash = 1; - - snprintf(bus_make.name.str, sizeof(bus_make.name.str), - "%u-%s", getuid(), name); - - 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 + - strlen(bus_make.name.str) + 1; - - bus_make.cmd.flags = KDBUS_MAKE_ACCESS_WORLD; - bus_make.cmd.size = sizeof(bus_make.cmd) + - bus_make.bp.size + - bus_make.attach.size + - bus_make.name.size; - - 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; - } - - if (ret == 0 && path) - *path = strdup(bus_make.name.str); - - return ret; -} - -struct kdbus_conn * -kdbus_hello(const char *path, uint64_t flags, - const struct kdbus_item *item, size_t item_size) -{ - struct kdbus_cmd_free cmd_free = {}; - int fd, ret; - struct { - struct kdbus_cmd_hello hello; - - struct { - uint64_t size; - uint64_t type; - char str[16]; - } conn_name; - - uint8_t extra_items[item_size]; - } h; - struct kdbus_conn *conn; - - memset(&h, 0, sizeof(h)); - - if (item_size > 0) - memcpy(h.extra_items, item, item_size); - - 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 = _KDBUS_ATTACH_ALL; - h.hello.attach_flags_recv = _KDBUS_ATTACH_ALL; - 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("-- Our peer ID for %s: %llu -- bus uuid: '%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'\n", - path, (unsigned long long)h.hello.id, - h.hello.id128[0], h.hello.id128[1], h.hello.id128[2], - h.hello.id128[3], h.hello.id128[4], h.hello.id128[5], - h.hello.id128[6], h.hello.id128[7], h.hello.id128[8], - h.hello.id128[9], h.hello.id128[10], h.hello.id128[11], - h.hello.id128[12], h.hello.id128[13], h.hello.id128[14], - h.hello.id128[15]); - - cmd_free.size = sizeof(cmd_free); - cmd_free.offset = h.hello.offset; - kdbus_cmd_free(fd, &cmd_free); - - 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) { - free(conn); - close(fd); - kdbus_printf("--- error mmap (%m)\n"); - return NULL; - } - - conn->fd = fd; - conn->id = h.hello.id; - return conn; -} - -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_item *item, *items; - size_t i, size; - - size = KDBUS_ITEM_SIZE(strlen(name) + 1) + - num_access * KDBUS_ITEM_SIZE(sizeof(*access)); - - items = alloca(size); - - item = items; - item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - item->type = KDBUS_ITEM_NAME; - strcpy(item->str, name); - item = KDBUS_ITEM_NEXT(item); - - for (i = 0; i < num_access; i++) { - item->size = KDBUS_ITEM_HEADER_SIZE + - sizeof(struct kdbus_policy_access); - item->type = KDBUS_ITEM_POLICY_ACCESS; - - item->policy_access.type = access[i].type; - item->policy_access.access = access[i].access; - item->policy_access.id = access[i].id; - - item = KDBUS_ITEM_NEXT(item); - } - - return kdbus_hello(path, flags, items, size); -} - -struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name, - const struct kdbus_policy_access *access, - size_t num_access) -{ - return kdbus_hello_registrar(path, name, access, num_access, - KDBUS_HELLO_ACTIVATOR); -} - -bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type) -{ - const struct kdbus_item *item; - - KDBUS_ITEM_FOREACH(item, msg, items) - if (item->type == type) - return true; - - return false; -} - -int kdbus_bus_creator_info(struct kdbus_conn *conn, - uint64_t flags, - uint64_t *offset) -{ - struct kdbus_cmd_info *cmd; - size_t size = sizeof(*cmd); - int ret; - - cmd = alloca(size); - memset(cmd, 0, size); - cmd->size = size; - cmd->attach_flags = flags; - - ret = kdbus_cmd_bus_creator_info(conn->fd, cmd); - if (ret < 0) { - kdbus_printf("--- error when requesting info: %d (%m)\n", ret); - return ret; - } - - if (offset) - *offset = cmd->offset; - else - kdbus_free(conn, cmd->offset); - - return 0; -} - -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); - struct kdbus_info *info; - int ret; - - if (name) - size += KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - - cmd = alloca(size); - memset(cmd, 0, size); - cmd->size = size; - cmd->attach_flags = flags; - - if (name) { - cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - cmd->items[0].type = KDBUS_ITEM_NAME; - strcpy(cmd->items[0].str, name); - } else { - cmd->id = id; - } - - ret = kdbus_cmd_conn_info(conn->fd, cmd); - if (ret < 0) { - kdbus_printf("--- error when requesting info: %d (%m)\n", ret); - return ret; - } - - info = (struct kdbus_info *) (conn->buf + cmd->offset); - if (info->size != cmd->info_size) { - kdbus_printf("%s(): size mismatch: %d != %d\n", __func__, - (int) info->size, (int) cmd->info_size); - return -EIO; - } - - if (offset) - *offset = cmd->offset; - else - kdbus_free(conn, cmd->offset); - - return 0; -} - -void kdbus_conn_free(struct kdbus_conn *conn) -{ - if (!conn) - return; - - if (conn->buf) - munmap(conn->buf, POOL_SIZE); - - if (conn->fd >= 0) - close(conn->fd); - - free(conn); -} - -int sys_memfd_create(const char *name, __u64 size) -{ - int ret, fd; - - fd = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING); - if (fd < 0) - return fd; - - ret = ftruncate(fd, size); - if (ret < 0) { - close(fd); - return ret; - } - - return fd; -} - -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) -{ - struct stat stat; - int ret; - - ret = fstat(fd, &stat); - if (ret < 0) { - kdbus_printf("stat() failed: %m\n"); - return ret; - } - - *size = stat.st_size; - return 0; -} - -static 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, - uint64_t cmd_flags, - int cancel_fd) -{ - 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; - struct timespec now; - uint64_t size; - int memfd = -1; - int ret; - - 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; - else { - memfd = sys_memfd_create("my-name-is-nice", 1024 * 1024); - if (memfd < 0) { - kdbus_printf("failed to create memfd: %m\n"); - return memfd; - } - - if (write(memfd, "kdbus memfd 1234567", 19) != 19) { - ret = -errno; - kdbus_printf("writing to memfd failed: %m\n"); - goto out; - } - - ret = sys_memfd_seal_set(memfd); - if (ret < 0) { - ret = -errno; - kdbus_printf("memfd sealing failed: %m\n"); - goto out; - } - - size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); - } - - if (name) - size += KDBUS_ITEM_SIZE(strlen(name) + 1); - - msg = malloc(size); - if (!msg) { - ret = -errno; - kdbus_printf("unable to malloc()!?\n"); - goto out; - } - - if (dst_id == KDBUS_DST_ID_BROADCAST) - flags |= KDBUS_MSG_SIGNAL; - - memset(msg, 0, size); - msg->flags = flags; - msg->priority = priority; - msg->size = size; - msg->src_id = conn->id; - msg->dst_id = name ? 0 : dst_id; - msg->cookie = cookie; - msg->payload_type = KDBUS_PAYLOAD_DBUS; - - if (timeout) { - ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now); - if (ret < 0) - goto out; - - msg->timeout_ns = now.tv_sec * 1000000000ULL + - now.tv_nsec + timeout; - } - - item = msg->items; - - if (name) { - item->type = KDBUS_ITEM_DST_NAME; - item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - strcpy(item->str, name); - item = KDBUS_ITEM_NEXT(item); - } - - item->type = KDBUS_ITEM_PAYLOAD_VEC; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); - item->vec.address = (uintptr_t)&ref1; - item->vec.size = sizeof(ref1); - item = KDBUS_ITEM_NEXT(item); - - /* data padding for ref1 */ - item->type = KDBUS_ITEM_PAYLOAD_VEC; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); - item->vec.address = (uintptr_t)NULL; - item->vec.size = KDBUS_ALIGN8(sizeof(ref1)) - sizeof(ref1); - item = KDBUS_ITEM_NEXT(item); - - item->type = KDBUS_ITEM_PAYLOAD_VEC; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); - item->vec.address = (uintptr_t)&ref2; - item->vec.size = sizeof(ref2); - item = KDBUS_ITEM_NEXT(item); - - if (dst_id == KDBUS_DST_ID_BROADCAST) { - item->type = KDBUS_ITEM_BLOOM_FILTER; - item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; - item->bloom_filter.generation = 0; - } else { - item->type = KDBUS_ITEM_PAYLOAD_MEMFD; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd); - item->memfd.size = 16; - item->memfd.fd = memfd; - } - item = KDBUS_ITEM_NEXT(item); - - size = sizeof(*cmd); - if (cancel_fd != -1) - size += KDBUS_ITEM_SIZE(sizeof(cancel_fd)); - - cmd = malloc(size); - if (!cmd) { - ret = -errno; - kdbus_printf("unable to malloc()!?\n"); - goto out; - } - - cmd->size = size; - cmd->flags = cmd_flags; - cmd->msg_address = (uintptr_t)msg; - - item = cmd->items; - - if (cancel_fd != -1) { - item->type = KDBUS_ITEM_CANCEL_FD; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(cancel_fd); - item->fds[0] = cancel_fd; - item = KDBUS_ITEM_NEXT(item); - } - - ret = kdbus_cmd_send(conn->fd, cmd); - if (ret < 0) { - kdbus_printf("error sending message: %d (%m)\n", ret); - goto out; - } - - if (cmd_flags & KDBUS_SEND_SYNC_REPLY) { - struct kdbus_msg *reply; - - kdbus_printf("SYNC REPLY @offset %llu:\n", cmd->reply.offset); - reply = (struct kdbus_msg *)(conn->buf + cmd->reply.offset); - kdbus_msg_dump(conn, reply); - - kdbus_msg_free(reply); - - ret = kdbus_free(conn, cmd->reply.offset); - if (ret < 0) - goto out; - } - -out: - free(msg); - free(cmd); - - if (memfd >= 0) - close(memfd); - - return ret < 0 ? ret : 0; -} - -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) -{ - return __kdbus_msg_send(conn, name, cookie, flags, timeout, priority, - dst_id, 0, -1); -} - -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); -} - -int kdbus_msg_send_reply(const struct kdbus_conn *conn, - uint64_t reply_cookie, - uint64_t dst_id) -{ - struct kdbus_cmd_send cmd = {}; - struct kdbus_msg *msg; - const char ref1[1024 * 128 + 3] = "0123456789_0"; - struct kdbus_item *item; - uint64_t size; - int ret; - - size = sizeof(struct kdbus_msg); - size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); - - msg = malloc(size); - if (!msg) { - kdbus_printf("unable to malloc()!?\n"); - return -ENOMEM; - } - - memset(msg, 0, size); - msg->size = size; - msg->src_id = conn->id; - msg->dst_id = dst_id; - msg->cookie_reply = reply_cookie; - msg->payload_type = KDBUS_PAYLOAD_DBUS; - - item = msg->items; - - item->type = KDBUS_ITEM_PAYLOAD_VEC; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); - item->vec.address = (uintptr_t)&ref1; - item->vec.size = sizeof(ref1); - item = KDBUS_ITEM_NEXT(item); - - cmd.size = sizeof(cmd); - cmd.msg_address = (uintptr_t)msg; - - ret = kdbus_cmd_send(conn->fd, &cmd); - if (ret < 0) - kdbus_printf("error sending message: %d (%m)\n", ret); - - free(msg); - - return ret; -} - -static char *msg_id(uint64_t id, char *buf) -{ - if (id == 0) - return "KERNEL"; - if (id == ~0ULL) - return "BROADCAST"; - sprintf(buf, "%llu", (unsigned long long)id); - return buf; -} - -int kdbus_msg_dump(const struct kdbus_conn *conn, const struct kdbus_msg *msg) -{ - const struct kdbus_item *item = msg->items; - char buf_src[32]; - char buf_dst[32]; - uint64_t timeout = 0; - uint64_t cookie_reply = 0; - int ret = 0; - - if (msg->flags & KDBUS_MSG_EXPECT_REPLY) - timeout = msg->timeout_ns; - else - cookie_reply = msg->cookie_reply; - - kdbus_printf("MESSAGE: %s (%llu bytes) flags=0x%08llx, %s → %s, " - "cookie=%llu, timeout=%llu cookie_reply=%llu priority=%lli\n", - 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), - (unsigned long long)msg->cookie, (unsigned long long)timeout, - (unsigned long long)cookie_reply, (long long)msg->priority); - - KDBUS_ITEM_FOREACH(item, msg, items) { - 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; - } - - switch (item->type) { - case KDBUS_ITEM_PAYLOAD_OFF: { - char *s; - - if (item->vec.offset == ~0ULL) - s = "[\\0-bytes]"; - else - s = (char *)msg + item->vec.offset; - - kdbus_printf(" +%s (%llu bytes) off=%llu size=%llu '%s'\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->vec.offset, - (unsigned long long)item->vec.size, s); - break; - } - - case KDBUS_ITEM_FDS: { - int i, n = (item->size - KDBUS_ITEM_HEADER_SIZE) / - sizeof(int); - - kdbus_printf(" +%s (%llu bytes, %d fds)\n", - enum_MSG(item->type), item->size, n); - - for (i = 0; i < n; i++) - kdbus_printf(" fd[%d] = %d\n", - i, item->fds[i]); - - break; - } - - case KDBUS_ITEM_PAYLOAD_MEMFD: { - char *buf; - off_t size; - - buf = mmap(NULL, item->memfd.size, PROT_READ, - MAP_PRIVATE, item->memfd.fd, 0); - if (buf == MAP_FAILED) { - kdbus_printf("mmap() fd=%i size=%llu failed: %m\n", - item->memfd.fd, item->memfd.size); - break; - } - - if (sys_memfd_get_size(item->memfd.fd, &size) < 0) { - kdbus_printf("KDBUS_CMD_MEMFD_SIZE_GET failed: %m\n"); - break; - } - - kdbus_printf(" +%s (%llu bytes) fd=%i size=%llu filesize=%llu '%s'\n", - enum_MSG(item->type), item->size, item->memfd.fd, - (unsigned long long)item->memfd.size, - (unsigned long long)size, buf); - munmap(buf, item->memfd.size); - break; - } - - case KDBUS_ITEM_CREDS: - kdbus_printf(" +%s (%llu bytes) uid=%lld, euid=%lld, suid=%lld, fsuid=%lld, " - "gid=%lld, egid=%lld, sgid=%lld, fsgid=%lld\n", - enum_MSG(item->type), item->size, - item->creds.uid, item->creds.euid, - item->creds.suid, item->creds.fsuid, - item->creds.gid, item->creds.egid, - item->creds.sgid, item->creds.fsgid); - break; - - case KDBUS_ITEM_PIDS: - kdbus_printf(" +%s (%llu bytes) pid=%lld, tid=%lld, ppid=%lld\n", - enum_MSG(item->type), item->size, - item->pids.pid, item->pids.tid, - item->pids.ppid); - break; - - case KDBUS_ITEM_AUXGROUPS: { - int i, n; - - kdbus_printf(" +%s (%llu bytes)\n", - enum_MSG(item->type), item->size); - n = (item->size - KDBUS_ITEM_HEADER_SIZE) / - sizeof(uint64_t); - - for (i = 0; i < n; i++) - kdbus_printf(" gid[%d] = %lld\n", - i, item->data64[i]); - break; - } - - case KDBUS_ITEM_NAME: - case KDBUS_ITEM_PID_COMM: - case KDBUS_ITEM_TID_COMM: - case KDBUS_ITEM_EXE: - case KDBUS_ITEM_CGROUP: - case KDBUS_ITEM_SECLABEL: - case KDBUS_ITEM_DST_NAME: - case KDBUS_ITEM_CONN_DESCRIPTION: - kdbus_printf(" +%s (%llu bytes) '%s' (%zu)\n", - enum_MSG(item->type), item->size, - item->str, strlen(item->str)); - break; - - case KDBUS_ITEM_OWNED_NAME: { - kdbus_printf(" +%s (%llu bytes) '%s' (%zu) flags=0x%08llx\n", - enum_MSG(item->type), item->size, - item->name.name, strlen(item->name.name), - item->name.flags); - break; - } - - case KDBUS_ITEM_CMDLINE: { - size_t size = item->size - KDBUS_ITEM_HEADER_SIZE; - const char *str = item->str; - int count = 0; - - kdbus_printf(" +%s (%llu bytes) ", - enum_MSG(item->type), item->size); - while (size) { - kdbus_printf("'%s' ", str); - size -= strlen(str) + 1; - str += strlen(str) + 1; - count++; - } - - kdbus_printf("(%d string%s)\n", - count, (count == 1) ? "" : "s"); - break; - } - - case KDBUS_ITEM_AUDIT: - kdbus_printf(" +%s (%llu bytes) loginuid=%u sessionid=%u\n", - enum_MSG(item->type), item->size, - item->audit.loginuid, item->audit.sessionid); - break; - - case KDBUS_ITEM_CAPS: { - const uint32_t *cap; - int n, i; - - kdbus_printf(" +%s (%llu bytes) len=%llu bytes, last_cap %d\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->size - - KDBUS_ITEM_HEADER_SIZE, - (int) item->caps.last_cap); - - cap = item->caps.caps; - n = (item->size - offsetof(struct kdbus_item, caps.caps)) - / 4 / sizeof(uint32_t); - - kdbus_printf(" CapInh="); - for (i = 0; i < n; i++) - kdbus_printf("%08x", cap[(0 * n) + (n - i - 1)]); - - kdbus_printf(" CapPrm="); - for (i = 0; i < n; i++) - kdbus_printf("%08x", cap[(1 * n) + (n - i - 1)]); - - kdbus_printf(" CapEff="); - for (i = 0; i < n; i++) - kdbus_printf("%08x", cap[(2 * n) + (n - i - 1)]); - - kdbus_printf(" CapBnd="); - for (i = 0; i < n; i++) - kdbus_printf("%08x", cap[(3 * n) + (n - i - 1)]); - kdbus_printf("\n"); - break; - } - - case KDBUS_ITEM_TIMESTAMP: - kdbus_printf(" +%s (%llu bytes) seq=%llu realtime=%lluns monotonic=%lluns\n", - enum_MSG(item->type), item->size, - (unsigned long long)item->timestamp.seqnum, - (unsigned long long)item->timestamp.realtime_ns, - (unsigned long long)item->timestamp.monotonic_ns); - break; - - case KDBUS_ITEM_REPLY_TIMEOUT: - kdbus_printf(" +%s (%llu bytes) cookie=%llu\n", - enum_MSG(item->type), item->size, - msg->cookie_reply); - break; - - case KDBUS_ITEM_NAME_ADD: - case KDBUS_ITEM_NAME_REMOVE: - case KDBUS_ITEM_NAME_CHANGE: - kdbus_printf(" +%s (%llu bytes) '%s', old id=%lld, now id=%lld, old_flags=0x%llx new_flags=0x%llx\n", - enum_MSG(item->type), - (unsigned long long) item->size, - item->name_change.name, - item->name_change.old_id.id, - item->name_change.new_id.id, - item->name_change.old_id.flags, - item->name_change.new_id.flags); - break; - - case KDBUS_ITEM_ID_ADD: - case KDBUS_ITEM_ID_REMOVE: - kdbus_printf(" +%s (%llu bytes) id=%llu flags=%llu\n", - enum_MSG(item->type), - (unsigned long long) item->size, - (unsigned long long) item->id_change.id, - (unsigned long long) item->id_change.flags); - break; - - default: - kdbus_printf(" +%s (%llu bytes)\n", - enum_MSG(item->type), item->size); - break; - } - } - - if ((char *)item - ((char *)msg + msg->size) >= 8) { - kdbus_printf("invalid padding at end of message\n"); - ret = -EINVAL; - } - - kdbus_printf("\n"); - - return ret; -} - -void kdbus_msg_free(struct kdbus_msg *msg) -{ - const struct kdbus_item *item; - int nfds, i; - - if (!msg) - return; - - KDBUS_ITEM_FOREACH(item, msg, items) { - switch (item->type) { - /* close all memfds */ - case KDBUS_ITEM_PAYLOAD_MEMFD: - 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]); - - break; - } - } -} - -int kdbus_msg_recv(struct kdbus_conn *conn, - struct kdbus_msg **msg_out, - uint64_t *offset) -{ - struct kdbus_cmd_recv recv = { .size = sizeof(recv) }; - struct kdbus_msg *msg; - int ret; - - ret = kdbus_cmd_recv(conn->fd, &recv); - if (ret < 0) - return ret; - - msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset); - ret = kdbus_msg_dump(conn, msg); - if (ret < 0) { - kdbus_msg_free(msg); - return ret; - } - - if (msg_out) { - *msg_out = msg; - - if (offset) - *offset = recv.msg.offset; - } else { - kdbus_msg_free(msg); - - ret = kdbus_free(conn, recv.msg.offset); - if (ret < 0) - return ret; - } - - return 0; -} - -/* - * Returns: 0 on success, negative errno on failure. - * - * 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, - int timeout_ms, - struct kdbus_msg **msg_out, - uint64_t *offset) -{ - int ret; - - do { - struct timeval before, after, diff; - struct pollfd fd; - - fd.fd = conn->fd; - fd.events = POLLIN | POLLPRI | POLLHUP; - fd.revents = 0; - - gettimeofday(&before, NULL); - ret = poll(&fd, 1, timeout_ms); - gettimeofday(&after, NULL); - - if (ret == 0) { - ret = -ETIMEDOUT; - break; - } - - if (ret > 0) { - if (fd.revents & POLLIN) - ret = kdbus_msg_recv(conn, msg_out, offset); - - if (fd.revents & (POLLHUP | POLLERR)) - ret = -ECONNRESET; - } - - if (ret == 0 || ret != -EAGAIN) - break; - - timersub(&after, &before, &diff); - timeout_ms -= diff.tv_sec * 1000UL + - diff.tv_usec / 1000UL; - } while (timeout_ms > 0); - - return ret; -} - -int kdbus_free(const struct kdbus_conn *conn, uint64_t offset) -{ - struct kdbus_cmd_free cmd_free = {}; - int ret; - - cmd_free.size = sizeof(cmd_free); - cmd_free.offset = offset; - cmd_free.flags = 0; - - ret = kdbus_cmd_free(conn->fd, &cmd_free); - if (ret < 0) { - kdbus_printf("KDBUS_CMD_FREE failed: %d (%m)\n", ret); - return ret; - } - - return 0; -} - -int kdbus_name_acquire(struct kdbus_conn *conn, - const char *name, uint64_t *flags) -{ - struct kdbus_cmd *cmd_name; - size_t name_len = strlen(name) + 1; - uint64_t size = sizeof(*cmd_name) + KDBUS_ITEM_SIZE(name_len); - struct kdbus_item *item; - int ret; - - cmd_name = alloca(size); - - memset(cmd_name, 0, size); - - item = cmd_name->items; - item->size = KDBUS_ITEM_HEADER_SIZE + name_len; - item->type = KDBUS_ITEM_NAME; - strcpy(item->str, name); - - cmd_name->size = size; - if (flags) - cmd_name->flags = *flags; - - ret = kdbus_cmd_name_acquire(conn->fd, cmd_name); - if (ret < 0) { - kdbus_printf("error aquiring name: %s\n", strerror(-ret)); - return ret; - } - - kdbus_printf("%s(): flags after call: 0x%llx\n", __func__, - cmd_name->return_flags); - - if (flags) - *flags = cmd_name->return_flags; - - return 0; -} - -int kdbus_name_release(struct kdbus_conn *conn, const char *name) -{ - struct kdbus_cmd *cmd_name; - size_t name_len = strlen(name) + 1; - uint64_t size = sizeof(*cmd_name) + KDBUS_ITEM_SIZE(name_len); - struct kdbus_item *item; - int ret; - - cmd_name = alloca(size); - - memset(cmd_name, 0, size); - - item = cmd_name->items; - item->size = KDBUS_ITEM_HEADER_SIZE + name_len; - item->type = KDBUS_ITEM_NAME; - strcpy(item->str, name); - - cmd_name->size = size; - - kdbus_printf("conn %lld giving up name '%s'\n", - (unsigned long long) conn->id, name); - - ret = kdbus_cmd_name_release(conn->fd, cmd_name); - if (ret < 0) { - kdbus_printf("error releasing name: %s\n", strerror(-ret)); - return ret; - } - - return 0; -} - -int kdbus_list(struct kdbus_conn *conn, uint64_t flags) -{ - struct kdbus_cmd_list cmd_list = {}; - struct kdbus_info *list, *name; - int ret; - - cmd_list.size = sizeof(cmd_list); - cmd_list.flags = flags; - - ret = kdbus_cmd_list(conn->fd, &cmd_list); - if (ret < 0) { - kdbus_printf("error listing names: %d (%m)\n", ret); - return ret; - } - - kdbus_printf("REGISTRY:\n"); - list = (struct kdbus_info *)(conn->buf + cmd_list.offset); - - KDBUS_FOREACH(name, list, cmd_list.list_size) { - uint64_t flags = 0; - struct kdbus_item *item; - const char *n = "MISSING-NAME"; - - if (name->size == sizeof(struct kdbus_cmd)) - continue; - - KDBUS_ITEM_FOREACH(item, name, items) - 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("\n"); - - ret = kdbus_free(conn, cmd_list.offset); - - return ret; -} - -int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, - uint64_t attach_flags_send, - uint64_t attach_flags_recv) -{ - int ret; - size_t size; - struct kdbus_cmd *update; - struct kdbus_item *item; - - size = sizeof(struct kdbus_cmd); - size += KDBUS_ITEM_SIZE(sizeof(uint64_t)) * 2; - - update = malloc(size); - if (!update) { - kdbus_printf("error malloc: %m\n"); - return -ENOMEM; - } - - memset(update, 0, size); - update->size = size; - - item = update->items; - - item->type = KDBUS_ITEM_ATTACH_FLAGS_SEND; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t); - item->data64[0] = attach_flags_send; - item = KDBUS_ITEM_NEXT(item); - - item->type = KDBUS_ITEM_ATTACH_FLAGS_RECV; - item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t); - item->data64[0] = attach_flags_recv; - item = KDBUS_ITEM_NEXT(item); - - ret = kdbus_cmd_update(conn->fd, update); - if (ret < 0) - kdbus_printf("error conn update: %d (%m)\n", ret); - - free(update); - - return ret; -} - -int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, - const struct kdbus_policy_access *access, - size_t num_access) -{ - struct kdbus_cmd *update; - struct kdbus_item *item; - size_t i, size; - int ret; - - size = sizeof(struct kdbus_cmd); - size += KDBUS_ITEM_SIZE(strlen(name) + 1); - size += num_access * KDBUS_ITEM_SIZE(sizeof(struct kdbus_policy_access)); - - update = malloc(size); - if (!update) { - kdbus_printf("error malloc: %m\n"); - return -ENOMEM; - } - - memset(update, 0, size); - update->size = size; - - item = update->items; - - item->type = KDBUS_ITEM_NAME; - item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - strcpy(item->str, name); - item = KDBUS_ITEM_NEXT(item); - - for (i = 0; i < num_access; i++) { - item->size = KDBUS_ITEM_HEADER_SIZE + - sizeof(struct kdbus_policy_access); - item->type = KDBUS_ITEM_POLICY_ACCESS; - - item->policy_access.type = access[i].type; - item->policy_access.access = access[i].access; - item->policy_access.id = access[i].id; - - item = KDBUS_ITEM_NEXT(item); - } - - ret = kdbus_cmd_update(conn->fd, update); - if (ret < 0) - kdbus_printf("error conn update: %d (%m)\n", ret); - - free(update); - - return ret; -} - -int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie, - uint64_t type, uint64_t id) -{ - struct { - struct kdbus_cmd_match cmd; - struct { - uint64_t size; - uint64_t type; - struct kdbus_notify_id_change chg; - } item; - } buf; - int ret; - - memset(&buf, 0, sizeof(buf)); - - buf.cmd.size = sizeof(buf); - buf.cmd.cookie = cookie; - buf.item.size = sizeof(buf.item); - buf.item.type = type; - buf.item.chg.id = id; - - ret = kdbus_cmd_match_add(conn->fd, &buf.cmd); - if (ret < 0) - kdbus_printf("--- error adding conn match: %d (%m)\n", ret); - - return ret; -} - -int kdbus_add_match_empty(struct kdbus_conn *conn) -{ - struct { - struct kdbus_cmd_match cmd; - struct kdbus_item item; - } buf; - int ret; - - memset(&buf, 0, sizeof(buf)); - - buf.item.size = sizeof(uint64_t) * 3; - buf.item.type = KDBUS_ITEM_ID; - buf.item.id = KDBUS_MATCH_ID_ANY; - - buf.cmd.size = sizeof(buf.cmd) + buf.item.size; - - ret = kdbus_cmd_match_add(conn->fd, &buf.cmd); - if (ret < 0) - kdbus_printf("--- error adding conn match: %d (%m)\n", ret); - - return ret; -} - -static int all_ids_are_mapped(const char *path) -{ - int ret; - FILE *file; - uint32_t inside_id, length; - - file = fopen(path, "r"); - if (!file) { - ret = -errno; - kdbus_printf("error fopen() %s: %d (%m)\n", - path, ret); - return ret; - } - - ret = fscanf(file, "%u\t%*u\t%u", &inside_id, &length); - if (ret != 2) { - if (ferror(file)) - ret = -errno; - else - ret = -EIO; - - kdbus_printf("--- error fscanf(): %d\n", ret); - fclose(file); - return ret; - } - - fclose(file); - - /* - * If length is 4294967295 which means the invalid uid - * (uid_t) -1 then we are able to map all uid/gids - */ - if (inside_id == 0 && length == (uid_t) -1) - return 1; - - return 0; -} - -int all_uids_gids_are_mapped(void) -{ - int ret; - - ret = all_ids_are_mapped("/proc/self/uid_map"); - if (ret <= 0) { - kdbus_printf("--- error not all uids are mapped\n"); - return 0; - } - - ret = all_ids_are_mapped("/proc/self/gid_map"); - if (ret <= 0) { - kdbus_printf("--- error not all gids are mapped\n"); - return 0; - } - - return 1; -} - -int drop_privileges(uid_t uid, gid_t gid) -{ - int ret; - - ret = setgroups(0, NULL); - if (ret < 0) { - ret = -errno; - kdbus_printf("error setgroups: %d (%m)\n", ret); - return ret; - } - - ret = setresgid(gid, gid, gid); - if (ret < 0) { - ret = -errno; - kdbus_printf("error setresgid: %d (%m)\n", ret); - return ret; - } - - ret = setresuid(uid, uid, uid); - if (ret < 0) { - ret = -errno; - kdbus_printf("error setresuid: %d (%m)\n", ret); - return ret; - } - - return ret; -} - -uint64_t now(clockid_t clock) -{ - struct timespec spec; - - clock_gettime(clock, &spec); - return spec.tv_sec * 1000ULL * 1000ULL * 1000ULL + spec.tv_nsec; -} - -char *unique_name(const char *prefix) -{ - unsigned int i; - uint64_t u_now; - char n[17]; - char *str; - int r; - - /* - * This returns a random string which is guaranteed to be - * globally unique across all calls to unique_name(). We - * compose the string as: - * --