From: Djalal Harouni Date: Tue, 14 Oct 2014 19:47:50 +0000 (+0100) Subject: test-activator: add more tests for the activation logic X-Git-Tag: upstream/0.20141102.012929utc~95 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c2ba8c3da5d8f602cab8b14d600a8c063628b3f9;p=platform%2Fcore%2Fsystem%2Fkdbus-bus.git test-activator: add more tests for the activation logic Signed-off-by: Djalal Harouni --- diff --git a/test/test-activator.c b/test/test-activator.c index b3c5710..8c73465 100644 --- a/test/test-activator.c +++ b/test/test-activator.c @@ -10,12 +10,228 @@ #include #include #include +#include +#include #include +#include #include "kdbus-test.h" #include "kdbus-util.h" #include "kdbus-enum.h" +static int kdbus_starter_poll(struct kdbus_conn *conn) +{ + int ret; + struct pollfd fd; + + fd.fd = conn->fd; + fd.events = POLLIN | POLLPRI | POLLHUP; + fd.revents = 0; + + ret = poll(&fd, 1, 100); + if (ret == 0) + return -ETIMEDOUT; + else if (ret > 0) { + if (fd.revents & POLLIN) + return 0; + + if (fd.revents & (POLLHUP | POLLERR)) + ret = -ECONNRESET; + } + + return ret; +} + +/* Ensure that kdbus activator logic is safe */ +static 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; + struct kdbus_conn *activator; + struct kdbus_conn *service; + struct kdbus_conn *client; + struct kdbus_conn *holder; + struct kdbus_policy_access *access; + + access = (struct kdbus_policy_access[]){ + { + .type = KDBUS_POLICY_ACCESS_USER, + .id = getuid(), + .access = KDBUS_POLICY_OWN, + }, + { + .type = KDBUS_POLICY_ACCESS_USER, + .id = getuid(), + .access = KDBUS_POLICY_TALK, + }, + }; + + activator = kdbus_hello_activator(env->buspath, "foo.priv.activator", + access, 2); + ASSERT_RETURN(activator); + + service = kdbus_hello(env->buspath, 0, NULL, 0); + ASSERT_RETURN(service); + + client = kdbus_hello(env->buspath, 0, NULL, 0); + ASSERT_RETURN(client); + + /* + * Make sure that other users can't TALK to the activator + */ + + ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + /* Try to talk using the ID */ + ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef, 0, 0, + 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); + ASSERT_EXIT(ret == -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); + + /* + * Now try to emulate the starter/service logic and + * acquire the name. + */ + + cookie++; + ret = kdbus_msg_send(service, "foo.priv.activator", cookie, + 0, 0, 0, KDBUS_DST_ID_NAME); + ASSERT_RETURN(ret == 0); + + ret = kdbus_starter_poll(activator); + ASSERT_RETURN(ret == 0); + + /* 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); + })); + ASSERT_RETURN(ret >= 0); + + ret = kdbus_name_acquire(service, "foo.priv.activator", + &flags); + ASSERT_RETURN(ret == 0); + + /* We read our previous starter message */ + + ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); + ASSERT_RETURN(ret == 0); + + /* Try to talk, we still fail */ + + cookie++; + ret = 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); + ASSERT_EXIT(ret == -EPERM); + })); + ASSERT_RETURN(ret >= 0); + + /* Still nothing to read */ + + ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); + ASSERT_RETURN(ret == -ETIMEDOUT); + + /* We receive every thing now */ + + cookie++; + ret = kdbus_msg_send(client, "foo.priv.activator", cookie, + 0, 0, 0, KDBUS_DST_ID_NAME); + ASSERT_RETURN(ret == 0); + ret = kdbus_msg_recv_poll(service, 100, &msg, NULL); + ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + + kdbus_msg_free(msg); + kdbus_free(service, msg->offset_reply); + + /* Policies default to deny TALK now */ + kdbus_conn_free(activator); + + cookie++; + ret = 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); + ASSERT_EXIT(ret == -EPERM); + })); + ASSERT_RETURN(ret >= 0); + + ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); + ASSERT_RETURN(ret == -ETIMEDOUT); + + /* Same user is able to TALK */ + cookie++; + ret = kdbus_msg_send(client, "foo.priv.activator", cookie, + 0, 0, 0, KDBUS_DST_ID_NAME); + ASSERT_RETURN(ret == 0); + ret = kdbus_msg_recv_poll(service, 100, &msg, NULL); + ASSERT_RETURN(ret == 0 && msg->cookie == cookie); + + kdbus_msg_free(msg); + kdbus_free(service, msg->offset_reply); + + access = (struct kdbus_policy_access []){ + { + .type = KDBUS_POLICY_ACCESS_WORLD, + .id = getuid(), + .access = KDBUS_POLICY_TALK, + }, + }; + + holder = kdbus_hello_registrar(env->buspath, "foo.priv.activator", + access, 1, KDBUS_HELLO_POLICY_HOLDER); + ASSERT_RETURN(holder); + + /* Now we are able to TALK to the name */ + + cookie++; + ret = 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); + ASSERT_EXIT(ret == 0); + })); + ASSERT_RETURN(ret >= 0); + + ret = kdbus_msg_recv_poll(service, 100, NULL, NULL); + ASSERT_RETURN(ret == 0); + + ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({ + ret = kdbus_name_acquire(unpriv, "foo.priv.activator", + &flags); + ASSERT_RETURN(ret == -EPERM); + })); + ASSERT_RETURN(ret >= 0); + + kdbus_conn_free(service); + kdbus_conn_free(client); + kdbus_conn_free(holder); + + return 0; +} + int kdbus_test_activator(struct kdbus_test_env *env) { int ret; @@ -85,6 +301,16 @@ 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); + + if (!ret) + return TEST_SKIP; + + ret = kdbus_priv_activator(env); + ASSERT_RETURN(ret == 0); + kdbus_conn_free(activator); return TEST_OK;