#undef DO_META
if (attach_flags & (KDBUS_ATTACH_AUXGROUPS|KDBUS_ATTACH_NAMES)
#ifdef CONFIG_SECURITY
- || missing_flags & KDBUS_ATTACH_SECLABEL
+ || missing_flags
#endif
) {
unsigned pay_size;
ret = 0;
}
#ifdef CONFIG_SECURITY
- if (missing_flags & KDBUS_ATTACH_SECLABEL && 0 > (ret = kdbus_meta_payload_collect_seclabel(&meta_payload)))
+ if (missing_flags && 0 > (ret = kdbus_meta_payload_collect_seclabel(&meta_payload)))
goto exit;
ret = 0;
#endif
include ../lib.mk
-%.o: %.c
+%.o: %.c $(wildcard *.h)
$(CC) $(CFLAGS) -c $< -o $@
kdbus-test: $(OBJS)
#define _TEST_KDBUS_H_
#include <pthread.h>
+#include <sys/syscall.h>
#include "kdbus-util.h"
struct kdbus_test_env {
TEST_TIME,
};
-extern pthread_mutex_t global_print_lock;
-
#if 0
#define print_assert_success print
#else
#define PRINTF_ARG(...) (_Generic((__VA_ARGS__),\
default: (__VA_ARGS__)))
-#define _ASSERT_REL_(val0, relop, val1, onfailure) do {\
+#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_)) { \
- /* had to partition into multiple print calls because _Generic does not play well with string constant concatenation */\
- pthread_mutex_lock(&global_print_lock);\
- print("Assertion '(");\
- print(PRINTF_FMT(_ASSERT_RETURN_VAL_val0_), PRINTF_ARG(_ASSERT_RETURN_VAL_val0_));\
- print("=%s) %s (", #val0, #relop);\
- print(PRINTF_FMT(_ASSERT_RETURN_VAL_val1_), PRINTF_ARG(_ASSERT_RETURN_VAL_val1_));\
- print("=%s)' failed in %s(), %s:%d\n", #val1, __func__, __FILE__, __LINE__);\
- pthread_mutex_unlock(&global_print_lock);\
- onfailure; \
+ /* 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", #val0 " " #relop " " #val1, __func__, __FILE__, __LINE__);\
+ else print_assert_success("Assertion '%s' SUCCEEDED in %s(), %s:%d\n", val0s " " #relop " " val1s, __func__, __FILE__, __LINE__);\
} while (0)
-#define ASSERT_RETURN_VAL(val0, relop, val1, retval) _ASSERT_REL_(val0, relop, val1, return retval)
-#define ASSERT_EXIT_VAL(val0, relop, val1, exitval) _ASSERT_REL_(val0, relop, val1, exit(exitval))
+#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(val0, relop, val1) ASSERT_RETURN_VAL(val0, relop, val1, TEST_ERR)
-#define ASSERT_EXIT(val0, relop, val1) ASSERT_EXIT_VAL(val0, relop, val1, 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_ZERO(...) ASSERT_RETURN((typeof((__VA_ARGS__)))0, ==, (__VA_ARGS__))
-#define ASSERT_NONZERO(...) ASSERT_RETURN((typeof((__VA_ARGS__)))0, !=, (__VA_ARGS__))
-#define ASSERT_EXIT_ZERO(...) ASSERT_EXIT((typeof((__VA_ARGS__)))0, ==, (__VA_ARGS__))
-#define ASSERT_EXIT_NONZERO(...) ASSERT_EXIT((typeof((__VA_ARGS__)))0, !=, (__VA_ARGS__))
+#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))
wur int kdbus_test_activator(struct kdbus_test_env *env);
wur int kdbus_test_benchmark(struct kdbus_test_env *env);
#include <time.h>
#include <stdbool.h>
#include <linux/kdbus.h>
+#include <sys/wait.h>
/* backwards-incompatible tizen customizations */
#define TIZEN
if (kdbus_util_verbose) \
print(X)
-#define RUN_UNPRIVILEGED(child_uid, child_gid, _child_, _parent_) ASSERT_ZERO(({ \
- 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_NONZERO(WIFEXITED(ret)); \
- ASSERT_ZERO(WEXITSTATUS(ret)); \
- 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_; \
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);
+wur int config_security_is_enabled(void);
\ No newline at end of file
return TEST_OK;
}
+static wur int set_label(char const *label)
+{
+ int fd = open("/proc/self/attr/current", O_RDWR);
+ ASSERT_RETURN(fd,>=,0);
+ int l = strlen(label);
+ ASSERT_NONZERO(l);
+ ASSERT_RETURN(l,==,write(fd, label, l));
+ ASSERT_ZERO(close(fd));
+ return 0;
+}
+
+static wur int assert_info_label(struct kdbus_conn *conn, uint64_t id, char const *label)
+{
+ uint64_t offset = 0;
+ ASSERT_ZERO(kdbus_conn_info(conn, id, NULL, KDBUS_ATTACH_SECLABEL, &offset));
+ struct kdbus_info *info = (struct kdbus_info *)(conn->buf + offset);
+ ASSERT_RETURN(info->id,==,id);
+ ASSERT_ZERO(assert_label(label, info->items));
+ ASSERT_ZERO(kdbus_free(conn, offset));
+ return 0;
+}
+
wur int kdbus_test_dynamic_seclabel(struct kdbus_test_env *env)
{
char const *labels[] = {"System::Privileged", "UserTest"};
unsigned i;
+
for (i=TABSIZE(labels); --i;) {
char const *label = labels[i];
- int fd = open("/proc/self/attr/current", O_RDWR);
- ASSERT_RETURN(fd,>=,0);
- int l = strlen(label);
- ASSERT_NONZERO(l);
- ASSERT_RETURN(l,==,write(fd, label, l));
- ASSERT_ZERO(close(fd));
-
+ ASSERT_ZERO(set_label(label));
{
struct kdbus_msg *msg;
ASSERT_ZERO(kdbus_msg_send(env->conn, NULL, 1, 0, 0, 0, env->conn->id));
ASSERT_ZERO(assert_label(label, msg->items));
kdbus_msg_free(msg);
}
+ ASSERT_ZERO(assert_info_label(env->conn, env->conn->id, label));
+ }
- {
- uint64_t offset = 0;
- ASSERT_ZERO(kdbus_conn_info(env->conn, env->conn->id, NULL, KDBUS_ATTACH_SECLABEL, &offset));
- struct kdbus_info *info = (struct kdbus_info *)(env->conn->buf + offset);
- ASSERT_RETURN(info->id,==,env->conn->id);
- ASSERT_ZERO(assert_label(label, info->items));
- ASSERT_ZERO(kdbus_free(env->conn, offset));
+ RUN_FORKED(({
+ struct kdbus_conn *child;
+ ASSERT_EXIT_ZERO(set_label("wuj"));
+ ASSERT_EXIT_NONZERO(child = kdbus_hello(env->buspath, 0, NULL, 0));
+ for (i=TABSIZE(labels); --i;) {
+ char const *label = labels[i];
+ ASSERT_EXIT_ZERO(kdbus_msg_send(child, NULL, 1+i, 0, 0, 0, env->conn->id));
+ {
+ struct kdbus_msg *msg;
+ ASSERT_EXIT_ZERO(kdbus_msg_recv_poll(child, 500, &msg, NULL));
+ ASSERT_EXIT(i,==,msg->cookie_reply-1);
+ ASSERT_EXIT_ZERO(assert_label(label, msg->items));
+ kdbus_msg_free(msg);
+ }
+ ASSERT_EXIT_ZERO(assert_info_label(child, env->conn->id, label));
}
- }
+ kdbus_conn_free(child);
+ }),
+ ({
+ for (i=TABSIZE(labels); --i;) {
+ struct kdbus_msg *msg;
+ ASSERT_ZERO(kdbus_msg_recv_poll(env->conn, 500, &msg, NULL));
+ ASSERT_RETURN(i,==,msg->cookie-1);
+ ASSERT_ZERO(set_label(labels[i]));
+ ASSERT_ZERO(assert_label("wuj", msg->items));
+ ASSERT_ZERO(kdbus_msg_send_reply(env->conn, i+1, msg->src_id));
+ ASSERT_ZERO(assert_info_label(env->conn, msg->src_id, "wuj"));
+ kdbus_msg_free(msg);
+ }
+ }));
return TEST_OK;
}