#include <config.h>
#include <lttng-consumerd.h>
+#include <lttng-ht.h>
#include <lttng-sessiond-comm.h>
#include <lttng/lttng-consumer.h>
#include <lttngerr.h>
+#include "common/runas.h"
#include "channel.h"
#include "compat/poll.h"
#include "context.h"
#include "event.h"
#include "futex.h"
-#include "hashtable.h"
#include "kernel.h"
#include "lttng-sessiond.h"
#include "shm.h"
int ust_consumerd64_fd = -1;
int ust_consumerd32_fd = -1;
-static const char *consumerd32_bin =
- __stringify(CONFIG_CONSUMERD32_BIN);
-static const char *consumerd64_bin =
- __stringify(CONFIG_CONSUMERD64_BIN);
-static const char *consumerd32_libdir =
- __stringify(CONFIG_CONSUMERD32_LIBDIR);
-static const char *consumerd64_libdir =
- __stringify(CONFIG_CONSUMERD64_LIBDIR);
+static const char *consumerd32_bin = CONFIG_CONSUMERD32_BIN;
+static const char *consumerd64_bin = CONFIG_CONSUMERD64_BIN;
+static const char *consumerd32_libdir = CONFIG_CONSUMERD32_LIBDIR;
+static const char *consumerd64_libdir = CONFIG_CONSUMERD64_LIBDIR;
static
void setup_consumerd_path(void)
*/
update_ust_app(ust_cmd.sock);
- ret = ustctl_register_done(ust_cmd.sock);
+ ret = ust_app_register_done(ust_cmd.sock);
if (ret < 0) {
/*
* If the registration is not possible, we simply
/*
* Exec consumerd.
*/
- if (opt_verbose > 1 || opt_verbose_consumer) {
+ if (opt_verbose_consumer) {
verbosity = "--verbose";
} else {
verbosity = "--quiet";
switch (consumer_data->type) {
case LTTNG_CONSUMER_KERNEL:
/*
- * Find out which consumerd to execute. We will
- * first try the 64-bit path, then the
- * sessiond's installation directory, and
- * fallback on the 32-bit one,
+ * Find out which consumerd to execute. We will first try the
+ * 64-bit path, then the sessiond's installation directory, and
+ * fallback on the 32-bit one,
*/
+ DBG3("Looking for a kernel consumer at these locations:");
+ DBG3(" 1) %s", consumerd64_bin);
+ DBG3(" 2) %s/%s", INSTALL_BIN_PATH, CONSUMERD_FILE);
+ DBG3(" 3) %s", consumerd32_bin);
if (stat(consumerd64_bin, &st) == 0) {
+ DBG3("Found location #1");
consumer_to_use = consumerd64_bin;
} else if (stat(INSTALL_BIN_PATH "/" CONSUMERD_FILE, &st) == 0) {
+ DBG3("Found location #2");
consumer_to_use = INSTALL_BIN_PATH "/" CONSUMERD_FILE;
} else if (stat(consumerd32_bin, &st) == 0) {
+ DBG3("Found location #3");
consumer_to_use = consumerd32_bin;
} else {
+ DBG("Could not find any valid consumerd executable");
break;
}
DBG("Using kernel consumer at: %s", consumer_to_use);
int ret;
char *type = "debugfs";
- ret = mkdir_recursive(path, S_IRWXU | S_IRWXG, geteuid(), getegid());
+ ret = run_as_mkdir_recursive(path, S_IRWXU | S_IRWXG, geteuid(), getegid());
if (ret < 0) {
PERROR("Cannot create debugfs path");
goto error;
goto error;
}
- ret = mkdir_recursive(lus->pathname, S_IRWXU | S_IRWXG,
+ ret = run_as_mkdir_recursive(lus->pathname, S_IRWXU | S_IRWXG,
session->uid, session->gid);
if (ret < 0) {
if (ret != -EEXIST) {
session->kernel_session->consumer_fd = kconsumer_data.cmd_sock;
}
- ret = mkdir_recursive(session->kernel_session->trace_path,
+ ret = run_as_mkdir_recursive(session->kernel_session->trace_path,
S_IRWXU | S_IRWXG, session->uid, session->gid);
if (ret < 0) {
if (ret != -EEXIST) {
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.
* 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);
break;
case LTTNG_DOMAIN_UST:
{
- struct cds_lfht_iter iter;
+ struct lttng_ht_iter iter;
struct ltt_ust_channel *uchan;
- cds_lfht_for_each_entry(session->ust_session->domain_global.channels,
- &iter, uchan, node) {
+ cds_lfht_for_each_entry(session->ust_session->domain_global.channels->ht,
+ &iter.iter, uchan, node.node) {
strncpy(channels[i].name, uchan->name, LTTNG_SYMBOL_NAME_LEN);
channels[i].attr.overwrite = uchan->attr.overwrite;
channels[i].attr.subbuf_size = uchan->attr.subbuf_size;
{
int i = 0, ret = 0;
unsigned int nb_event = 0;
- struct cds_lfht_iter iter;
- struct cds_lfht_node *node;
+ struct lttng_ht_iter iter;
+ struct lttng_ht_node_str *node;
struct ltt_ust_channel *uchan;
struct ltt_ust_event *uevent;
struct lttng_event *tmp;
rcu_read_lock();
- node = hashtable_lookup(ust_global->channels, (void *) channel_name,
- strlen(channel_name), &iter);
+ lttng_ht_lookup(ust_global->channels, (void *)channel_name, &iter);
+ node = lttng_ht_iter_get_node_str(&iter);
if (node == NULL) {
ret = -LTTCOMM_UST_CHAN_NOT_FOUND;
goto error;
}
- uchan = caa_container_of(node, struct ltt_ust_channel, node);
+ uchan = caa_container_of(&node->node, struct ltt_ust_channel, node.node);
- nb_event += hashtable_get_count(uchan->events);
+ nb_event += lttng_ht_get_count(uchan->events);
if (nb_event == 0) {
ret = nb_event;
goto error;
}
- cds_lfht_for_each_entry(uchan->events, &iter, uevent, node) {
+ cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) {
strncpy(tmp[i].name, uevent->attr.name, LTTNG_SYMBOL_NAME_LEN);
tmp[i].name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
tmp[i].enabled = uevent->enabled;
case LTTNG_DOMAIN_UST:
{
struct ltt_ust_channel *uchan;
- struct cds_lfht *chan_ht;
+ struct lttng_ht *chan_ht;
chan_ht = usess->domain_global.channels;
{
int ret;
struct ltt_ust_session *usess = session->ust_session;
- struct cds_lfht *chan_ht;
+ struct lttng_ht *chan_ht;
DBG("Enabling channel %s for session %s", attr->name, session->name);
}
/* At this point, the session and channel exist on the tracer */
-
ret = event_ust_enable_tracepoint(usess, domain, uchan, event);
if (ret != LTTCOMM_OK) {
goto error;
usess = session->ust_session;
if (!session->enabled) {
- ret = LTTCOMM_UST_START_FAIL;
+ ret = LTTCOMM_UST_STOP_FAIL;
goto error;
}
ret = ust_app_stop_trace_all(usess);
if (ret < 0) {
- ret = LTTCOMM_UST_START_FAIL;
+ ret = LTTCOMM_UST_STOP_FAIL;
goto error;
}
}
break;
case LTTNG_DOMAIN_UST:
if (session->ust_session != NULL) {
- nb_chan = hashtable_get_count(
+ nb_chan = lttng_ht_get_count(
session->ust_session->domain_global.channels);
}
DBG3("Number of UST global channels %zd", nb_chan);
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:
}
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();