From: Mathieu Desnoyers Date: Wed, 21 Dec 2011 15:21:29 +0000 (-0500) Subject: Only allow the user or group owning the session (or root) to control a session X-Git-Tag: v2.0-pre16~5 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=8e0af1b4e36284b519bac6b13928a7589db4da11 Only allow the user or group owning the session (or root) to control a session Signed-off-by: Mathieu Desnoyers --- diff --git a/include/lttng-sessiond-comm.h b/include/lttng-sessiond-comm.h index c72a2471e..48cf93321 100644 --- a/include/lttng-sessiond-comm.h +++ b/include/lttng-sessiond-comm.h @@ -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 */ diff --git a/liblttng-sessiond-comm/lttng-sessiond-comm.c b/liblttng-sessiond-comm/lttng-sessiond-comm.c index cf12e6aca..483b346d6 100644 --- a/liblttng-sessiond-comm/lttng-sessiond-comm.c +++ b/liblttng-sessiond-comm/lttng-sessiond-comm.c @@ -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", diff --git a/lttng-sessiond/main.c b/lttng-sessiond/main.c index 10139448a..402e228ba 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -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();