Only allow the user or group owning the session (or root) to control a session
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 21 Dec 2011 15:21:29 +0000 (10:21 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 21 Dec 2011 15:21:29 +0000 (10:21 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/lttng-sessiond-comm.h
liblttng-sessiond-comm/lttng-sessiond-comm.c
lttng-sessiond/main.c

index c72a2471e85005b0727a4ecc882ccb2fb56779ec..48cf933216c431ece31185b7fc55bb4ee5816f8b 100644 (file)
@@ -97,6 +97,7 @@ enum lttcomm_return_code {
        LTTCOMM_NO_EVENT,                               /* No event found */
        LTTCOMM_CONNECT_FAIL,           /* Unable to connect to unix socket */
        LTTCOMM_APP_NOT_FOUND,          /* App not found in traceable app list */
+       LTTCOMM_EPERM,                  /* Permission denied */
        LTTCOMM_KERN_NA,                                /* Kernel tracer unavalable */
        LTTCOMM_KERN_EVENT_EXIST,       /* Kernel event already exists */
        LTTCOMM_KERN_SESS_FAIL,                 /* Kernel create session failed */
index cf12e6acac64577f9e4b8e172678b48a27b86874..483b346d6692072513f3d59a0f79332b00d1a587 100644 (file)
@@ -53,6 +53,7 @@ static const char *lttcomm_readable_code[] = {
        [ LTTCOMM_ERR_INDEX(LTTCOMM_EXIST_SESS) ] = "Session name already exist",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_CONNECT_FAIL) ] = "Unable to connect to Unix socket",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_APP_NOT_FOUND) ] = "Application not found",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_EPERM) ] = "Permission denied",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_NA) ] = "Kernel tracer not available",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_EVENT_EXIST) ] = "Kernel event already exists",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_SESS_FAIL) ] = "Kernel create session failed",
index 10139448aee3dcbe811c75adb3ca55a99c9b5d4d..402e228bab4c18c850a6136cd9f102d3d62563d6 100644 (file)
@@ -1965,6 +1965,40 @@ error:
        return ret;
 }
 
+/*
+ * Check if the UID or GID match the session. Root user has access to
+ * all sessions.
+ */
+static int session_access_ok(struct ltt_session *session,
+        uid_t uid, gid_t gid)
+{
+       if (uid != session->uid && gid != session->gid
+                       && uid != 0) {
+               return 0;
+       } else {
+               return 1;
+       }
+}
+
+static unsigned int lttng_sessions_count(uid_t uid, gid_t gid)
+{
+       unsigned int i = 0;
+       struct ltt_session *session;
+
+       DBG("Counting number of available session for UID %d GID %d",
+               uid, gid);
+       cds_list_for_each_entry(session, &session_list_ptr->head, list) {
+               /*
+                * Only list the sessions the user can control.
+                */
+               if (!session_access_ok(session, uid, gid)) {
+                       continue;
+               }
+               i++;
+       }
+       return i;
+}
+
 /*
  * Using the session list, filled a lttng_session array to send back to the
  * client for session listing.
@@ -1972,17 +2006,25 @@ error:
  * The session list lock MUST be acquired before calling this function. Use
  * session_lock_list() and session_unlock_list().
  */
-static void list_lttng_sessions(struct lttng_session *sessions)
+static void list_lttng_sessions(struct lttng_session *sessions,
+               uid_t uid, gid_t gid)
 {
-       int i = 0;
+       unsigned int i = 0;
        struct ltt_session *session;
 
-       DBG("Getting all available session");
+       DBG("Getting all available session for UID %d GID %d",
+               uid, gid);
        /*
         * Iterate over session list and append data after the control struct in
         * the buffer.
         */
        cds_list_for_each_entry(session, &session_list_ptr->head, list) {
+               /*
+                * Only list the sessions the user can control.
+                */
+               if (!session_access_ok(session, uid, gid)) {
+                       continue;
+               }
                strncpy(sessions[i].path, session->path, PATH_MAX);
                sessions[i].path[PATH_MAX - 1] = '\0';
                strncpy(sessions[i].name, session->name, NAME_MAX);
@@ -3316,6 +3358,18 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                break;
        }
 
+       /*
+        * Check that the UID or GID match that of the tracing session.
+        * The root user can interact with all sessions.
+        */
+       if (need_tracing_session) {
+               if (!session_access_ok(cmd_ctx->session,
+                               cmd_ctx->creds.uid, cmd_ctx->creds.gid)) {
+                       ret = LTTCOMM_EPERM;
+                       goto error;
+               }
+       }
+
        /* Process by command type */
        switch (cmd_ctx->lsm->cmd_type) {
        case LTTNG_ADD_CONTEXT:
@@ -3501,23 +3555,24 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
        }
        case LTTNG_LIST_SESSIONS:
        {
-               session_lock_list();
+               unsigned int nr_sessions;
 
-               if (session_list_ptr->count == 0) {
+               session_lock_list();
+               nr_sessions = lttng_sessions_count(cmd_ctx->creds.uid, cmd_ctx->creds.gid);
+               if (nr_sessions == 0) {
                        ret = LTTCOMM_NO_SESSION;
                        session_unlock_list();
                        goto error;
                }
-
-               ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) *
-                               session_list_ptr->count);
+               ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * nr_sessions);
                if (ret < 0) {
                        session_unlock_list();
                        goto setup_error;
                }
 
                /* Filled the session array */
-               list_lttng_sessions((struct lttng_session *)(cmd_ctx->llm->payload));
+               list_lttng_sessions((struct lttng_session *)(cmd_ctx->llm->payload),
+                       cmd_ctx->creds.uid, cmd_ctx->creds.gid);
 
                session_unlock_list();
 
This page took 0.038504 seconds and 4 git commands to generate.