Move to kernel style SPDX license identifiers
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
index e7978744be681894d9cad7b769855597c09af0f1..cfe2cc960a8e52c580982c09815b8ac681204ac1 100644 (file)
@@ -1,25 +1,16 @@
 /*
- * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
- * Copyright (C) 2011-2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Copyright (C) 2011 Julien Desfossez <julien.desfossez@polymtl.ca>
+ * Copyright (C) 2011-2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  */
 
 #include <stdint.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 
 #include <lttng/ust-config.h>
 #include <lttng/ust-ctl.h>
@@ -36,6 +27,7 @@
 #include "../liblttng-ust/lttng-rb-clients.h"
 #include "../liblttng-ust/clock.h"
 #include "../liblttng-ust/getenv.h"
+#include "../liblttng-ust/lttng-tracer-core.h"
 
 #include "../libcounter/shm.h"
 #include "../libcounter/smp.h"
@@ -99,9 +91,13 @@ extern void lttng_ring_buffer_client_overwrite_rt_exit(void);
 extern void lttng_ring_buffer_client_discard_exit(void);
 extern void lttng_ring_buffer_client_discard_rt_exit(void);
 extern void lttng_ring_buffer_metadata_client_exit(void);
+LTTNG_HIDDEN
 extern void lttng_counter_client_percpu_32_modular_init(void);
+LTTNG_HIDDEN
 extern void lttng_counter_client_percpu_32_modular_exit(void);
+LTTNG_HIDDEN
 extern void lttng_counter_client_percpu_64_modular_init(void);
+LTTNG_HIDDEN
 extern void lttng_counter_client_percpu_64_modular_exit(void);
 
 int ustctl_release_handle(int sock, int handle)
@@ -562,6 +558,7 @@ int ustctl_create_event_notifier(int sock, struct lttng_ust_event_notifier *even
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
        struct lttng_ust_object_data *event_notifier_data;
+       ssize_t len;
        int ret;
 
        if (!event_notifier_group || !_event_notifier_data)
@@ -576,15 +573,22 @@ int ustctl_create_event_notifier(int sock, struct lttng_ust_event_notifier *even
        memset(&lum, 0, sizeof(lum));
        lum.handle = event_notifier_group->handle;
        lum.cmd = LTTNG_UST_EVENT_NOTIFIER_CREATE;
+       lum.u.event_notifier.len = sizeof(*event_notifier);
 
-       strncpy(lum.u.event_notifier.event.name, event_notifier->event.name,
-               LTTNG_UST_SYM_NAME_LEN);
-       lum.u.event_notifier.event.instrumentation = event_notifier->event.instrumentation;
-       lum.u.event_notifier.event.loglevel_type = event_notifier->event.loglevel_type;
-       lum.u.event_notifier.event.loglevel = event_notifier->event.loglevel;
-       lum.u.event_notifier.event.token = event_notifier->event.token;
-       lum.u.event_notifier.error_counter_index = event_notifier->error_counter_index;
-       ret = ustcomm_send_app_cmd(sock, &lum, &lur);
+       ret = ustcomm_send_app_msg(sock, &lum);
+       if (ret) {
+               free(event_notifier_data);
+               return ret;
+       }
+       /* Send struct lttng_ust_event_notifier */
+       len = ustcomm_send_unix_sock(sock, event_notifier, sizeof(*event_notifier));
+       if (len != sizeof(*event_notifier)) {
+               if (len < 0)
+                       return len;
+               else
+                       return -EIO;
+       }
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
        if (ret) {
                free(event_notifier_data);
                return ret;
@@ -2009,6 +2013,105 @@ int ustctl_has_perf_counters(void)
 
 #endif
 
+#ifdef __linux__
+/*
+ * Override application pid/uid/gid with unix socket credentials. If
+ * the application announced a pid matching our view, it means it is
+ * within the same pid namespace, so expose the ppid provided by the
+ * application.
+ */
+static
+int get_cred(int sock,
+       const struct ustctl_reg_msg *reg_msg,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid)
+{
+       struct ucred ucred;
+       socklen_t ucred_len = sizeof(struct ucred);
+       int ret;
+
+       ret = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len);
+       if (ret) {
+               return -LTTNG_UST_ERR_PEERCRED;
+       }
+       DBG("Unix socket peercred [ pid: %u, uid: %u, gid: %u ], "
+               "application registered claiming [ pid: %u, ppid: %u, uid: %u, gid: %u ]",
+               ucred.pid, ucred.uid, ucred.gid,
+               reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
+       if (!ucred.pid) {
+               ERR("Unix socket credential pid=0. Refusing application in distinct, non-nested pid namespace.");
+               return -LTTNG_UST_ERR_PEERCRED_PID;
+       }
+       *pid = ucred.pid;
+       *uid = ucred.uid;
+       *gid = ucred.gid;
+       if (ucred.pid == reg_msg->pid) {
+               *ppid = reg_msg->ppid;
+       } else {
+               *ppid = 0;
+       }
+       return 0;
+}
+#elif defined(__FreeBSD__)
+#include <sys/ucred.h>
+#include <sys/un.h>
+
+/*
+ * Override application uid/gid with unix socket credentials. Use the
+ * first group of the cr_groups.
+ * Use the pid and ppid provided by the application on registration.
+ */
+static
+int get_cred(int sock,
+       const struct ustctl_reg_msg *reg_msg,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid)
+{
+       struct xucred xucred;
+       socklen_t xucred_len = sizeof(struct xucred);
+       int ret;
+
+       ret = getsockopt(sock, SOL_SOCKET, LOCAL_PEERCRED, &xucred, &xucred_len);
+       if (ret) {
+               return -LTTNG_UST_ERR_PEERCRED;
+       }
+       if (xucred.cr_version != XUCRED_VERSION || xucred.cr_ngroups < 1) {
+               return -LTTNG_UST_ERR_PEERCRED;
+       }
+       DBG("Unix socket peercred [ uid: %u, gid: %u ], "
+               "application registered claiming [ pid: %d, ppid: %d, uid: %u, gid: %u ]",
+               xucred.cr_uid, xucred.cr_groups[0],
+               reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
+       *pid = reg_msg->pid;
+       *ppid = reg_msg->ppid;
+       *uid = xucred.cr_uid;
+       *gid = xucred.cr_groups[0];
+       return 0;
+}
+#else
+#warning "Using insecure fallback: trusting user id provided by registered applications. Please consider implementing use of unix socket credentials on your platform."
+static
+int get_cred(int sock,
+       const struct ustctl_reg_msg *reg_msg,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid)
+{
+       DBG("Application registered claiming [ pid: %u, ppid: %d, uid: %u, gid: %u ]",
+               reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
+       *pid = reg_msg->pid;
+       *ppid = reg_msg->ppid;
+       *uid = reg_msg->uid;
+       *gid = reg_msg->gid;
+       return 0;
+}
+#endif
+
 /*
  * Returns 0 on success, negative error value on error.
  */
@@ -2059,10 +2162,6 @@ int ustctl_recv_reg_msg(int sock,
        }
        *major = reg_msg.major;
        *minor = reg_msg.minor;
-       *pid = reg_msg.pid;
-       *ppid = reg_msg.ppid;
-       *uid = reg_msg.uid;
-       *gid = reg_msg.gid;
        *bits_per_long = reg_msg.bits_per_long;
        *uint8_t_alignment = reg_msg.uint8_t_alignment;
        *uint16_t_alignment = reg_msg.uint16_t_alignment;
@@ -2074,8 +2173,7 @@ int ustctl_recv_reg_msg(int sock,
                        reg_msg.major > LTTNG_UST_ABI_MAJOR_VERSION) {
                return -LTTNG_UST_ERR_UNSUP_MAJOR;
        }
-
-       return 0;
+       return get_cred(sock, &reg_msg, pid, ppid, uid, gid);
 }
 
 int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd)
@@ -2563,7 +2661,7 @@ int ustctl_create_counter_data(struct ustctl_daemon_counter *counter,
                struct lttng_ust_object_data **_counter_data)
 {
        struct lttng_ust_object_data *counter_data;
-       struct lttng_ust_counter_conf counter_conf;
+       struct lttng_ust_counter_conf counter_conf = {0};
        size_t i;
        int ret;
 
@@ -2579,10 +2677,10 @@ int ustctl_create_counter_data(struct ustctl_daemon_counter *counter,
        }
        switch (counter->attr->bitness) {
        case USTCTL_COUNTER_BITNESS_32:
-               counter_conf.bitness = LTTNG_UST_COUNTER_BITNESS_32BITS;
+               counter_conf.bitness = LTTNG_UST_COUNTER_BITNESS_32;
                break;
        case USTCTL_COUNTER_BITNESS_64:
-               counter_conf.bitness = LTTNG_UST_COUNTER_BITNESS_64BITS;
+               counter_conf.bitness = LTTNG_UST_COUNTER_BITNESS_64;
                break;
        default:
                return -EINVAL;
This page took 0.025301 seconds and 4 git commands to generate.