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)
.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
* 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 */
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
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);
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);
}),
({
/* 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 */
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);
* 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);
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);
}
* 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) {
.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);
/* 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);
/*
* 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");
* 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;
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;
+}