All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH lttng-ust 1/2] RFC: Add userspace namespace contexts
       [not found] <1520369615-10782-1-git-send-email-mjeanson@efficios.com>
@ 2018-03-06 20:53 ` Michael Jeanson
  2018-03-06 20:53 ` [PATCH lttng-ust 2/2] RFC: Add userspace vuid/vgid contexts Michael Jeanson
  1 sibling, 0 replies; 2+ messages in thread
From: Michael Jeanson @ 2018-03-06 20:53 UTC (permalink / raw)
  To: lttng-dev

Add a context for each available kernel namespace which currently are :
cgroup, ipc, mnt, net, pid, user and uts. The id chosen to identify the
namespaces is the inode number of the fd representing each of them in
the proc filesystem.

This was introduced in kernel v3.8.0, if any of these context are
enabled on a system running an older kernel, zero will be returned.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
---
 include/lttng/ust-abi.h                |   7 ++
 include/lttng/ust-events.h             |  14 ++++
 include/lttng/ust.h                    |   2 +
 liblttng-ust-fork/ustfork.c            |  50 ++++++++++++
 liblttng-ust/Makefile.am               |   7 ++
 liblttng-ust/lttng-context-cgroup-ns.c | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-ipc-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-mnt-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-net-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-pid-ns.c    | 122 ++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-user-ns.c   | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-uts-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context.c           |  35 ++++++++
 liblttng-ust/lttng-events.c            |  14 ++++
 liblttng-ust/lttng-tracer-core.h       |  14 ++++
 liblttng-ust/lttng-ust-comm.c          |  29 +++++++
 16 files changed, 1158 insertions(+)
 create mode 100644 liblttng-ust/lttng-context-cgroup-ns.c
 create mode 100644 liblttng-ust/lttng-context-ipc-ns.c
 create mode 100644 liblttng-ust/lttng-context-mnt-ns.c
 create mode 100644 liblttng-ust/lttng-context-net-ns.c
 create mode 100644 liblttng-ust/lttng-context-pid-ns.c
 create mode 100644 liblttng-ust/lttng-context-user-ns.c
 create mode 100644 liblttng-ust/lttng-context-uts-ns.c

diff --git a/include/lttng/ust-abi.h b/include/lttng/ust-abi.h
index 4976b1b..0e0c954 100644
--- a/include/lttng/ust-abi.h
+++ b/include/lttng/ust-abi.h
@@ -141,6 +141,13 @@ enum lttng_ust_context_type {
 	LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER	= 5,
 	LTTNG_UST_CONTEXT_CPU_ID		= 6,
 	LTTNG_UST_CONTEXT_APP_CONTEXT		= 7,
+	LTTNG_UST_CONTEXT_CGROUP_NS		= 8,
+	LTTNG_UST_CONTEXT_IPC_NS		= 9,
+	LTTNG_UST_CONTEXT_MNT_NS		= 10,
+	LTTNG_UST_CONTEXT_NET_NS		= 11,
+	LTTNG_UST_CONTEXT_PID_NS		= 12,
+	LTTNG_UST_CONTEXT_USER_NS		= 13,
+	LTTNG_UST_CONTEXT_UTS_NS		= 14,
 };
 
 struct lttng_ust_perf_counter_ctx {
diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h
index 8673350..4f1ee45 100644
--- a/include/lttng/ust-events.h
+++ b/include/lttng/ust-events.h
@@ -674,8 +674,22 @@ int lttng_add_procname_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_ip_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_cpu_id_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_dyntest_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_cgroup_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_ipc_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_mnt_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx);
 void lttng_context_vtid_reset(void);
 void lttng_context_vpid_reset(void);
+void lttng_context_cgroup_ns_reset(void);
+void lttng_context_ipc_ns_reset(void);
+void lttng_context_mnt_ns_reset(void);
+void lttng_context_net_ns_reset(void);
+void lttng_context_pid_ns_reset(void);
+void lttng_context_user_ns_reset(void);
+void lttng_context_uts_ns_reset(void);
 
 #ifdef LTTNG_UST_HAVE_PERF_EVENT
 int lttng_add_perf_counter_to_ctx(uint32_t type,
diff --git a/include/lttng/ust.h b/include/lttng/ust.h
index 2779d7a..0b2a897 100644
--- a/include/lttng/ust.h
+++ b/include/lttng/ust.h
@@ -32,6 +32,8 @@ extern "C" {
 extern void ust_before_fork(sigset_t *save_sigset);
 extern void ust_after_fork_parent(sigset_t *restore_sigset);
 extern void ust_after_fork_child(sigset_t *restore_sigset);
+extern void ust_after_setns(void);
+extern void ust_after_unshare(void);
 
 #ifdef __cplusplus 
 }
diff --git a/liblttng-ust-fork/ustfork.c b/liblttng-ust-fork/ustfork.c
index 71c4b86..25f9d4c 100644
--- a/liblttng-ust-fork/ustfork.c
+++ b/liblttng-ust-fork/ustfork.c
@@ -160,6 +160,56 @@ int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...)
 	return retval;
 }
 
+int setns(int fd, int nstype)
+{
+	static int (*plibc_func)(int fd, int nstype) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setns");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setns\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setns */
+	retval = plibc_func(fd, nstype);
+	saved_errno = errno;
+
+	ust_after_setns();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int unshare(int flags)
+{
+	static int (*plibc_func)(int flags) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "unshare");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"unshare\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setns */
+	retval = plibc_func(flags);
+	saved_errno = errno;
+
+	ust_after_unshare();
+
+	errno = saved_errno;
+	return retval;
+}
+
 #elif defined (__FreeBSD__)
 
 pid_t rfork(int flags)
diff --git a/liblttng-ust/Makefile.am b/liblttng-ust/Makefile.am
index a7edfd5..bdcc325 100644
--- a/liblttng-ust/Makefile.am
+++ b/liblttng-ust/Makefile.am
@@ -30,6 +30,13 @@ liblttng_ust_runtime_la_SOURCES = \
 	lttng-context-procname.c \
 	lttng-context-ip.c \
 	lttng-context-cpu-id.c \
+	lttng-context-cgroup-ns.c \
+	lttng-context-ipc-ns.c \
+	lttng-context-mnt-ns.c \
+	lttng-context-net-ns.c \
+	lttng-context-pid-ns.c \
+	lttng-context-user-ns.c \
+	lttng-context-uts-ns.c \
 	lttng-context.c \
 	lttng-events.c \
 	lttng-filter.c \
diff --git a/liblttng-ust/lttng-context-cgroup-ns.c b/liblttng-ust/lttng-context-cgroup-ns.c
new file mode 100644
index 0000000..e1d92ca
--- /dev/null
+++ b/liblttng-ust/lttng-context-cgroup-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-cgroup-ns.c
+ *
+ * LTTng UST cgroup namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_cgroup_ns);
+
+static
+unsigned int get_cgroup_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_cgroup_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/cgroup", &sb) == 0) {
+			URCU_TLS(cached_cgroup_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/cgroup",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_cgroup_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_cgroup_ns);
+}
+
+/*
+ * The cgroup namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWCGROUP
+ *  * setns(2) called with the fd of a different cgroup ns
+ *  * unshare(2) called with CLONE_NEWCGROUP
+ */
+void lttng_context_cgroup_ns_reset(void)
+{
+	URCU_TLS(cached_cgroup_ns) = 0;
+}
+
+static
+size_t cgroup_ns_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+	size += sizeof(unsigned int);
+	return size;
+}
+
+static
+void cgroup_ns_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int cgroup_ns;
+
+	cgroup_ns = get_cgroup_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(cgroup_ns));
+	chan->ops->event_write(ctx, &cgroup_ns, sizeof(cgroup_ns));
+}
+
+static
+void cgroup_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int cgroup_ns;
+
+	cgroup_ns = get_cgroup_ns();
+	value->u.s64 = cgroup_ns;
+}
+
+int lttng_add_cgroup_ns_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "cgroup_ns")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "cgroup_ns";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = cgroup_ns_get_size;
+	field->record = cgroup_ns_record;
+	field->get_value = cgroup_ns_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_cgroup_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_cgroup_ns)));
+}
diff --git a/liblttng-ust/lttng-context-ipc-ns.c b/liblttng-ust/lttng-context-ipc-ns.c
new file mode 100644
index 0000000..b52994e
--- /dev/null
+++ b/liblttng-ust/lttng-context-ipc-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-ipc-ns.c
+ *
+ * LTTng UST ipc namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_ipc_ns);
+
+static
+unsigned int get_ipc_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_ipc_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/ipc", &sb) == 0) {
+			URCU_TLS(cached_ipc_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/ipc",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_ipc_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_ipc_ns);
+}
+
+/*
+ * The ipc namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWIPC
+ *  * setns(2) called with the fd of a different ipc ns
+ *  * unshare(2) called with CLONE_NEWIPC
+ */
+void lttng_context_ipc_ns_reset(void)
+{
+	URCU_TLS(cached_ipc_ns) = 0;
+}
+
+static
+size_t ipc_ns_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+	size += sizeof(unsigned int);
+	return size;
+}
+
+static
+void ipc_ns_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int ipc_ns;
+
+	ipc_ns = get_ipc_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(ipc_ns));
+	chan->ops->event_write(ctx, &ipc_ns, sizeof(ipc_ns));
+}
+
+static
+void ipc_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int ipc_ns;
+
+	ipc_ns = get_ipc_ns();
+	value->u.s64 = ipc_ns;
+}
+
+int lttng_add_ipc_ns_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "ipc_ns")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "ipc_ns";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = ipc_ns_get_size;
+	field->record = ipc_ns_record;
+	field->get_value = ipc_ns_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_ipc_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_ipc_ns)));
+}
diff --git a/liblttng-ust/lttng-context-mnt-ns.c b/liblttng-ust/lttng-context-mnt-ns.c
new file mode 100644
index 0000000..b19e438
--- /dev/null
+++ b/liblttng-ust/lttng-context-mnt-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-mnt-ns.c
+ *
+ * LTTng UST mnt namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_mnt_ns);
+
+static
+unsigned int get_mnt_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_mnt_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/mnt", &sb) == 0) {
+			URCU_TLS(cached_mnt_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/mnt",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_mnt_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_mnt_ns);
+}
+
+/*
+ * The mnt namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWNS
+ *  * setns(2) called with the fd of a different mnt ns
+ *  * unshare(2) called with CLONE_NEWNS
+ */
+void lttng_context_mnt_ns_reset(void)
+{
+	URCU_TLS(cached_mnt_ns) = 0;
+}
+
+static
+size_t mnt_ns_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+	size += sizeof(unsigned int);
+	return size;
+}
+
+static
+void mnt_ns_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int mnt_ns;
+
+	mnt_ns = get_mnt_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(mnt_ns));
+	chan->ops->event_write(ctx, &mnt_ns, sizeof(mnt_ns));
+}
+
+static
+void mnt_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int mnt_ns;
+
+	mnt_ns = get_mnt_ns();
+	value->u.s64 = mnt_ns;
+}
+
+int lttng_add_mnt_ns_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "mnt_ns")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "mnt_ns";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = mnt_ns_get_size;
+	field->record = mnt_ns_record;
+	field->get_value = mnt_ns_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_mnt_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_mnt_ns)));
+}
diff --git a/liblttng-ust/lttng-context-net-ns.c b/liblttng-ust/lttng-context-net-ns.c
new file mode 100644
index 0000000..53512e0
--- /dev/null
+++ b/liblttng-ust/lttng-context-net-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-net-ns.c
+ *
+ * LTTng UST net namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_net_ns);
+
+static
+unsigned int get_net_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_net_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/net", &sb) == 0) {
+			URCU_TLS(cached_net_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/net",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_net_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_net_ns);
+}
+
+/*
+ * The net namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWNET
+ *  * setns(2) called with the fd of a different net ns
+ *  * unshare(2) called with CLONE_NEWNET
+ */
+void lttng_context_net_ns_reset(void)
+{
+	URCU_TLS(cached_net_ns) = 0;
+}
+
+static
+size_t net_ns_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+	size += sizeof(unsigned int);
+	return size;
+}
+
+static
+void net_ns_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int net_ns;
+
+	net_ns = get_net_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(net_ns));
+	chan->ops->event_write(ctx, &net_ns, sizeof(net_ns));
+}
+
+static
+void net_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int net_ns;
+
+	net_ns = get_net_ns();
+	value->u.s64 = net_ns;
+}
+
+int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "net_ns")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "net_ns";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = net_ns_get_size;
+	field->record = net_ns_record;
+	field->get_value = net_ns_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_net_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_net_ns)));
+}
diff --git a/liblttng-ust/lttng-context-pid-ns.c b/liblttng-ust/lttng-context-pid-ns.c
new file mode 100644
index 0000000..030cbc3
--- /dev/null
+++ b/liblttng-ust/lttng-context-pid-ns.c
@@ -0,0 +1,122 @@
+/*
+ * lttng-context-pid-ns.c
+ *
+ * LTTng UST pid namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. The PID namespace is global to the process.
+ */
+static unsigned int cached_pid_ns;
+
+static
+unsigned int get_pid_ns(void)
+{
+	if (caa_unlikely(!cached_pid_ns)) {
+		struct stat sb;
+
+		if (stat("/proc/self/ns/pid", &sb) == 0) {
+			cached_pid_ns = sb.st_ino;
+		}
+	}
+
+	return cached_pid_ns;
+}
+
+/*
+ * A process's PID namespace membership is determined when the process is
+ * created and cannot be changed thereafter.
+ *
+ * The pid namespace can change only on clone(2) / fork(2) :
+ *  - clone(2) with the CLONE_NEWPID flag
+ *  - clone(2) / fork(2) after a call to unshare(2) with the CLONE_NEWPID flag
+ *  - clone(2) / fork(2) after a call to setns(2) with a PID namespace fd
+ */
+void lttng_context_pid_ns_reset(void)
+{
+	cached_pid_ns = 0;
+}
+
+static
+size_t pid_ns_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+	size += sizeof(unsigned int);
+	return size;
+}
+
+static
+void pid_ns_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int pid_ns;
+
+	pid_ns = get_pid_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(pid_ns));
+	chan->ops->event_write(ctx, &pid_ns, sizeof(pid_ns));
+}
+
+static
+void pid_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int pid_ns;
+
+	pid_ns = get_pid_ns();
+	value->u.s64 = pid_ns;
+}
+
+int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "pid_ns")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "pid_ns";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = pid_ns_get_size;
+	field->record = pid_ns_record;
+	field->get_value = pid_ns_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context-user-ns.c b/liblttng-ust/lttng-context-user-ns.c
new file mode 100644
index 0000000..e26463f
--- /dev/null
+++ b/liblttng-ust/lttng-context-user-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-user-ns.c
+ *
+ * LTTng UST user namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_user_ns);
+
+static
+unsigned int get_user_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_user_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/user", &sb) == 0) {
+			URCU_TLS(cached_user_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/user",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_user_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_user_ns);
+}
+
+/*
+ * The user namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWUSER
+ *  * setns(2) called with the fd of a different user ns
+ *  * unshare(2) called with CLONE_NEWUSER
+ */
+void lttng_context_user_ns_reset(void)
+{
+	URCU_TLS(cached_user_ns) = 0;
+}
+
+static
+size_t user_ns_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+	size += sizeof(unsigned int);
+	return size;
+}
+
+static
+void user_ns_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int user_ns;
+
+	user_ns = get_user_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(user_ns));
+	chan->ops->event_write(ctx, &user_ns, sizeof(user_ns));
+}
+
+static
+void user_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int user_ns;
+
+	user_ns = get_user_ns();
+	value->u.s64 = user_ns;
+}
+
+int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "user_ns")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "user_ns";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = user_ns_get_size;
+	field->record = user_ns_record;
+	field->get_value = user_ns_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_user_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_user_ns)));
+}
diff --git a/liblttng-ust/lttng-context-uts-ns.c b/liblttng-ust/lttng-context-uts-ns.c
new file mode 100644
index 0000000..aa79b03
--- /dev/null
+++ b/liblttng-ust/lttng-context-uts-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-uts-ns.c
+ *
+ * LTTng UST uts namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_uts_ns);
+
+static
+unsigned int get_uts_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_uts_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/uts", &sb) == 0) {
+			URCU_TLS(cached_uts_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/uts",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_uts_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_uts_ns);
+}
+
+/*
+ * The uts namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWUTS
+ *  * setns(2) called with the fd of a different uts ns
+ *  * unshare(2) called with CLONE_NEWUTS
+ */
+void lttng_context_uts_ns_reset(void)
+{
+	URCU_TLS(cached_uts_ns) = 0;
+}
+
+static
+size_t uts_ns_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+	size += sizeof(unsigned int);
+	return size;
+}
+
+static
+void uts_ns_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int uts_ns;
+
+	uts_ns = get_uts_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(uts_ns));
+	chan->ops->event_write(ctx, &uts_ns, sizeof(uts_ns));
+}
+
+static
+void uts_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int uts_ns;
+
+	uts_ns = get_uts_ns();
+	value->u.s64 = uts_ns;
+}
+
+int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "uts_ns")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "uts_ns";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = uts_ns_get_size;
+	field->record = uts_ns_record;
+	field->get_value = uts_ns_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_uts_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_uts_ns)));
+}
diff --git a/liblttng-ust/lttng-context.c b/liblttng-ust/lttng-context.c
index eeaaae4..ad6c38f 100644
--- a/liblttng-ust/lttng-context.c
+++ b/liblttng-ust/lttng-context.c
@@ -372,6 +372,41 @@ int lttng_session_context_init(struct lttng_ctx **ctx)
 		WARN("Cannot add context lttng_add_cpu_id_to_ctx");
 		goto error;
 	}
+	ret = lttng_add_cgroup_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_cgroup_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_ipc_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_ipc_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_mnt_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_mnt_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_net_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_net_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_pid_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_pid_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_user_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_user_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_uts_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_uts_ns_to_ctx");
+		goto error;
+	}
 	lttng_context_update(*ctx);
 	return 0;
 
diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c
index 255c4b9..329aae0 100644
--- a/liblttng-ust/lttng-events.c
+++ b/liblttng-ust/lttng-events.c
@@ -1112,6 +1112,20 @@ int lttng_attach_context(struct lttng_ust_context *context_param,
 	case LTTNG_UST_CONTEXT_APP_CONTEXT:
 		return lttng_ust_add_app_context_to_ctx_rcu(uargs->app_context.ctxname,
 			ctx);
+	case LTTNG_UST_CONTEXT_CGROUP_NS:
+		return lttng_add_cgroup_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_IPC_NS:
+		return lttng_add_ipc_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_MNT_NS:
+		return lttng_add_mnt_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_NET_NS:
+		return lttng_add_net_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_PID_NS:
+		return lttng_add_pid_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_USER_NS:
+		return lttng_add_user_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_UTS_NS:
+		return lttng_add_uts_ns_to_ctx(ctx);
 	default:
 		return -EINVAL;
 	}
diff --git a/liblttng-ust/lttng-tracer-core.h b/liblttng-ust/lttng-tracer-core.h
index ba232f3..d249d19 100644
--- a/liblttng-ust/lttng-tracer-core.h
+++ b/liblttng-ust/lttng-tracer-core.h
@@ -30,6 +30,14 @@
 #include <lttng/ringbuffer-config.h>
 #include <usterr-signal-safe.h>
 
+/*
+ * The longuest possible namespace proc path is with the cgroup ns
+ * and the maximum theoretical linux pid of 536870912 :
+ *
+ *  /proc/self/task/536870912/ns/cgroup
+ */
+#define LTTNG_PROC_NS_PATH_MAX 40
+
 struct lttng_session;
 struct lttng_channel;
 struct lttng_event;
@@ -44,6 +52,12 @@ void ust_unlock(void);
 void lttng_fixup_event_tls(void);
 void lttng_fixup_vtid_tls(void);
 void lttng_fixup_procname_tls(void);
+void lttng_fixup_cgroup_ns_tls(void);
+void lttng_fixup_ipc_ns_tls(void);
+void lttng_fixup_mnt_ns_tls(void);
+void lttng_fixup_net_ns_tls(void);
+void lttng_fixup_user_ns_tls(void);
+void lttng_fixup_uts_ns_tls(void);
 
 const char *lttng_ust_obj_get_name(int id);
 
diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c
index d4add1c..eda4904 100644
--- a/liblttng-ust/lttng-ust-comm.c
+++ b/liblttng-ust/lttng-ust-comm.c
@@ -411,6 +411,12 @@ void lttng_ust_fixup_tls(void)
 	lttng_fixup_procname_tls();
 	lttng_fixup_ust_mutex_nest_tls();
 	lttng_ust_fixup_fd_tracker_tls();
+	lttng_fixup_cgroup_ns_tls();
+	lttng_fixup_ipc_ns_tls();
+	lttng_fixup_mnt_ns_tls();
+	lttng_fixup_net_ns_tls();
+	lttng_fixup_user_ns_tls();
+	lttng_fixup_uts_ns_tls();
 }
 
 int lttng_get_notify_socket(void *owner)
@@ -1936,6 +1942,18 @@ void __attribute__((destructor)) lttng_ust_exit(void)
 	lttng_ust_cleanup(1);
 }
 
+static
+void ust_context_ns_reset(void)
+{
+	lttng_context_pid_ns_reset();
+	lttng_context_cgroup_ns_reset();
+	lttng_context_ipc_ns_reset();
+	lttng_context_mnt_ns_reset();
+	lttng_context_net_ns_reset();
+	lttng_context_user_ns_reset();
+	lttng_context_uts_ns_reset();
+}
+
 /*
  * We exclude the worker threads across fork and clone (except
  * CLONE_VM), because these system calls only keep the forking thread
@@ -2013,6 +2031,7 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 		return;
 	lttng_context_vpid_reset();
 	lttng_context_vtid_reset();
+	ust_context_ns_reset();
 	DBG("process %d", getpid());
 	/* Release urcu mutexes */
 	rcu_bp_after_fork_child();
@@ -2022,6 +2041,16 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 	lttng_ust_init();
 }
 
+void ust_after_setns(void)
+{
+	ust_context_ns_reset();
+}
+
+void ust_after_unshare(void)
+{
+	ust_context_ns_reset();
+}
+
 void lttng_ust_sockinfo_session_enabled(void *owner)
 {
 	struct sock_info *sock_info = owner;
-- 
2.7.4



_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH lttng-ust 2/2] RFC: Add userspace vuid/vgid contexts
       [not found] <1520369615-10782-1-git-send-email-mjeanson@efficios.com>
  2018-03-06 20:53 ` [PATCH lttng-ust 1/2] RFC: Add userspace namespace contexts Michael Jeanson
@ 2018-03-06 20:53 ` Michael Jeanson
  1 sibling, 0 replies; 2+ messages in thread
From: Michael Jeanson @ 2018-03-06 20:53 UTC (permalink / raw)
  To: lttng-dev

Add a context for each available namespaced user and group IDs

  * vuid : real user ID
  * veuid : effective user ID
  * vsuid : saved set-user ID

These are the IDs as seen in the current user namespace, see
user_namespaces(7) and credentials(7) for details on each type.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
---
 include/lttng/ust-abi.h            |   6 ++
 include/lttng/ust-events.h         |  12 +++
 include/lttng/ust.h                |   8 ++
 liblttng-ust-fork/ustfork.c        | 200 +++++++++++++++++++++++++++++++++++++
 liblttng-ust/Makefile.am           |   6 ++
 liblttng-ust/lttng-context-vegid.c | 123 +++++++++++++++++++++++
 liblttng-ust/lttng-context-veuid.c | 123 +++++++++++++++++++++++
 liblttng-ust/lttng-context-vgid.c  | 123 +++++++++++++++++++++++
 liblttng-ust/lttng-context-vsgid.c | 129 ++++++++++++++++++++++++
 liblttng-ust/lttng-context-vsuid.c | 130 ++++++++++++++++++++++++
 liblttng-ust/lttng-context-vuid.c  | 123 +++++++++++++++++++++++
 liblttng-ust/lttng-context.c       |  30 ++++++
 liblttng-ust/lttng-events.c        |  12 +++
 liblttng-ust/lttng-ust-comm.c      |  62 ++++++++++++
 14 files changed, 1087 insertions(+)
 create mode 100644 liblttng-ust/lttng-context-vegid.c
 create mode 100644 liblttng-ust/lttng-context-veuid.c
 create mode 100644 liblttng-ust/lttng-context-vgid.c
 create mode 100644 liblttng-ust/lttng-context-vsgid.c
 create mode 100644 liblttng-ust/lttng-context-vsuid.c
 create mode 100644 liblttng-ust/lttng-context-vuid.c

diff --git a/include/lttng/ust-abi.h b/include/lttng/ust-abi.h
index 0e0c954..411b6ce 100644
--- a/include/lttng/ust-abi.h
+++ b/include/lttng/ust-abi.h
@@ -148,6 +148,12 @@ enum lttng_ust_context_type {
 	LTTNG_UST_CONTEXT_PID_NS		= 12,
 	LTTNG_UST_CONTEXT_USER_NS		= 13,
 	LTTNG_UST_CONTEXT_UTS_NS		= 14,
+	LTTNG_UST_CONTEXT_VUID			= 15,
+	LTTNG_UST_CONTEXT_VEUID			= 16,
+	LTTNG_UST_CONTEXT_VSUID			= 17,
+	LTTNG_UST_CONTEXT_VGID			= 18,
+	LTTNG_UST_CONTEXT_VEGID			= 19,
+	LTTNG_UST_CONTEXT_VSGID			= 20,
 };
 
 struct lttng_ust_perf_counter_ctx {
diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h
index 4f1ee45..5e04d23 100644
--- a/include/lttng/ust-events.h
+++ b/include/lttng/ust-events.h
@@ -681,6 +681,12 @@ int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vuid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_veuid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vsuid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vgid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vegid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vsgid_to_ctx(struct lttng_ctx **ctx);
 void lttng_context_vtid_reset(void);
 void lttng_context_vpid_reset(void);
 void lttng_context_cgroup_ns_reset(void);
@@ -690,6 +696,12 @@ void lttng_context_net_ns_reset(void);
 void lttng_context_pid_ns_reset(void);
 void lttng_context_user_ns_reset(void);
 void lttng_context_uts_ns_reset(void);
+void lttng_context_vuid_reset(void);
+void lttng_context_veuid_reset(void);
+void lttng_context_vsuid_reset(void);
+void lttng_context_vgid_reset(void);
+void lttng_context_vegid_reset(void);
+void lttng_context_vsgid_reset(void);
 
 #ifdef LTTNG_UST_HAVE_PERF_EVENT
 int lttng_add_perf_counter_to_ctx(uint32_t type,
diff --git a/include/lttng/ust.h b/include/lttng/ust.h
index 0b2a897..7befe83 100644
--- a/include/lttng/ust.h
+++ b/include/lttng/ust.h
@@ -34,6 +34,14 @@ extern void ust_after_fork_parent(sigset_t *restore_sigset);
 extern void ust_after_fork_child(sigset_t *restore_sigset);
 extern void ust_after_setns(void);
 extern void ust_after_unshare(void);
+extern void ust_after_setuid(void);
+extern void ust_after_setgid(void);
+extern void ust_after_seteuid(void);
+extern void ust_after_setegid(void);
+extern void ust_after_setreuid(void);
+extern void ust_after_setregid(void);
+extern void ust_after_setresuid(void);
+extern void ust_after_setresgid(void);
 
 #ifdef __cplusplus 
 }
diff --git a/liblttng-ust-fork/ustfork.c b/liblttng-ust-fork/ustfork.c
index 25f9d4c..983ed04 100644
--- a/liblttng-ust-fork/ustfork.c
+++ b/liblttng-ust-fork/ustfork.c
@@ -89,6 +89,156 @@ int daemon(int nochdir, int noclose)
 	return retval;
 }
 
+int setuid(uid_t uid)
+{
+	static int (*plibc_func)(uid_t uid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setuid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setuid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setuid */
+	retval = plibc_func(uid);
+	saved_errno = errno;
+
+	ust_after_setuid();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int setgid(gid_t gid)
+{
+	static int (*plibc_func)(gid_t gid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setgid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setgid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setgid */
+	retval = plibc_func(gid);
+	saved_errno = errno;
+
+	ust_after_setgid();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int seteuid(uid_t euid)
+{
+	static int (*plibc_func)(uid_t euid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "seteuid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"seteuid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real seteuid */
+	retval = plibc_func(euid);
+	saved_errno = errno;
+
+	ust_after_seteuid();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int setegid(gid_t egid)
+{
+	static int (*plibc_func)(gid_t egid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setegid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setegid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setegid */
+	retval = plibc_func(egid);
+	saved_errno = errno;
+
+	ust_after_setegid();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int setreuid(uid_t ruid, uid_t euid)
+{
+	static int (*plibc_func)(uid_t ruid, uid_t euid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setreuid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setreuid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setreuid */
+	retval = plibc_func(ruid, euid);
+	saved_errno = errno;
+
+	ust_after_setreuid();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int setregid(gid_t rgid, gid_t egid)
+{
+	static int (*plibc_func)(gid_t rgid, gid_t egid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setregid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setregid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setregid */
+	retval = plibc_func(rgid, egid);
+	saved_errno = errno;
+
+	ust_after_setregid();
+
+	errno = saved_errno;
+	return retval;
+}
+
 #ifdef __linux__
 
 struct user_desc;
@@ -210,6 +360,56 @@ int unshare(int flags)
 	return retval;
 }
 
+int setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+	static int (*plibc_func)(uid_t ruid, uid_t euid, uid_t suid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setresuid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setresuid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setresuid */
+	retval = plibc_func(ruid, euid, suid);
+	saved_errno = errno;
+
+	ust_after_setresuid();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+	static int (*plibc_func)(gid_t rgid, gid_t egid, gid_t sgid) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setresgid");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setresgid\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setresgid */
+	retval = plibc_func(rgid, egid, sgid);
+	saved_errno = errno;
+
+	ust_after_setresgid();
+
+	errno = saved_errno;
+	return retval;
+}
+
 #elif defined (__FreeBSD__)
 
 pid_t rfork(int flags)
diff --git a/liblttng-ust/Makefile.am b/liblttng-ust/Makefile.am
index bdcc325..470712c 100644
--- a/liblttng-ust/Makefile.am
+++ b/liblttng-ust/Makefile.am
@@ -37,6 +37,12 @@ liblttng_ust_runtime_la_SOURCES = \
 	lttng-context-pid-ns.c \
 	lttng-context-user-ns.c \
 	lttng-context-uts-ns.c \
+	lttng-context-vuid.c \
+	lttng-context-veuid.c \
+	lttng-context-vsuid.c \
+	lttng-context-vgid.c \
+	lttng-context-vegid.c \
+	lttng-context-vsgid.c \
 	lttng-context.c \
 	lttng-events.c \
 	lttng-filter.c \
diff --git a/liblttng-ust/lttng-context-vegid.c b/liblttng-ust/lttng-context-vegid.c
new file mode 100644
index 0000000..31830cc
--- /dev/null
+++ b/liblttng-ust/lttng-context-vegid.c
@@ -0,0 +1,123 @@
+/*
+ * lttng-context-vegid.c
+ *
+ * LTTng UST namespaced effective group ID context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+/*
+ * At the kernel level, user IDs and group IDs are a per-thread attribute.
+ * However, POSIX requires that all threads in a process share the same
+ * credentials. The NPTL threading implementation handles the POSIX
+ * requirements by providing wrapper functions for the various system calls
+ * that change process UIDs and GIDs. These wrapper functions (including those
+ * for setreuid() and setregid()) employ a signal-based technique to ensure
+ * that when one thread changes credentials, all of the other threads in the
+ * process also change their credentials.
+ */
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. User / group IDs are global to the process.
+ */
+static gid_t cached_vegid = (gid_t) -1;
+
+static
+gid_t get_vegid(void)
+{
+	if (caa_unlikely(cached_vegid == (gid_t) -1)) {
+		cached_vegid = getegid();
+	}
+
+	return cached_vegid;
+}
+
+/*
+ * The vegid can change on setuid, setreuid, setresuid and seteuid.
+ */
+void lttng_context_vegid_reset(void)
+{
+	cached_vegid = (gid_t) -1;
+}
+
+static
+size_t vegid_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(gid_t));
+	size += sizeof(gid_t);
+	return size;
+}
+
+static
+void vegid_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	gid_t vegid;
+
+	vegid = get_vegid();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(vegid));
+	chan->ops->event_write(ctx, &vegid, sizeof(vegid));
+}
+
+static
+void vegid_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	gid_t vegid;
+
+	vegid = get_vegid();
+	value->u.s64 = vegid;
+}
+
+int lttng_add_vegid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vegid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vegid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vegid_get_size;
+	field->record = vegid_record;
+	field->get_value = vegid_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context-veuid.c b/liblttng-ust/lttng-context-veuid.c
new file mode 100644
index 0000000..536770e
--- /dev/null
+++ b/liblttng-ust/lttng-context-veuid.c
@@ -0,0 +1,123 @@
+/*
+ * lttng-context-veuid.c
+ *
+ * LTTng UST namespaced effective user ID context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+/*
+ * At the kernel level, user IDs and group IDs are a per-thread attribute.
+ * However, POSIX requires that all threads in a process share the same
+ * credentials. The NPTL threading implementation handles the POSIX
+ * requirements by providing wrapper functions for the various system calls
+ * that change process UIDs and GIDs. These wrapper functions (including those
+ * for setreuid() and setregid()) employ a signal-based technique to ensure
+ * that when one thread changes credentials, all of the other threads in the
+ * process also change their credentials.
+ */
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. User / group IDs are global to the process.
+ */
+static uid_t cached_veuid = (uid_t) -1;
+
+static
+uid_t get_veuid(void)
+{
+	if (caa_unlikely(cached_veuid == (uid_t) -1)) {
+		cached_veuid = geteuid();
+	}
+
+	return cached_veuid;
+}
+
+/*
+ * The veuid can change on setuid, setreuid, setresuid and seteuid.
+ */
+void lttng_context_veuid_reset(void)
+{
+	cached_veuid = (uid_t) -1;
+}
+
+static
+size_t veuid_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(uid_t));
+	size += sizeof(uid_t);
+	return size;
+}
+
+static
+void veuid_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	uid_t veuid;
+
+	veuid = get_veuid();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(veuid));
+	chan->ops->event_write(ctx, &veuid, sizeof(veuid));
+}
+
+static
+void veuid_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	uid_t veuid;
+
+	veuid = get_veuid();
+	value->u.s64 = veuid;
+}
+
+int lttng_add_veuid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "veuid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "veuid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = veuid_get_size;
+	field->record = veuid_record;
+	field->get_value = veuid_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context-vgid.c b/liblttng-ust/lttng-context-vgid.c
new file mode 100644
index 0000000..3586e8f
--- /dev/null
+++ b/liblttng-ust/lttng-context-vgid.c
@@ -0,0 +1,123 @@
+/*
+ * lttng-context-vgid.c
+ *
+ * LTTng UST namespaced real group ID context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+/*
+ * At the kernel level, user IDs and group IDs are a per-thread attribute.
+ * However, POSIX requires that all threads in a process share the same
+ * credentials. The NPTL threading implementation handles the POSIX
+ * requirements by providing wrapper functions for the various system calls
+ * that change process UIDs and GIDs. These wrapper functions (including those
+ * for setreuid() and setregid()) employ a signal-based technique to ensure
+ * that when one thread changes credentials, all of the other threads in the
+ * process also change their credentials.
+ */
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. User / group IDs are global to the process.
+ */
+static gid_t cached_vgid = (gid_t) -1;
+
+static
+gid_t get_vgid(void)
+{
+	if (caa_unlikely(cached_vgid == (gid_t) -1)) {
+		cached_vgid = getgid();
+	}
+
+	return cached_vgid;
+}
+
+/*
+ * The vgid can change on setuid, setreuid and setresuid.
+ */
+void lttng_context_vgid_reset(void)
+{
+	cached_vgid = (gid_t) -1;
+}
+
+static
+size_t vgid_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(gid_t));
+	size += sizeof(gid_t);
+	return size;
+}
+
+static
+void vgid_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	gid_t vgid;
+
+	vgid = get_vgid();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(vgid));
+	chan->ops->event_write(ctx, &vgid, sizeof(vgid));
+}
+
+static
+void vgid_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	gid_t vgid;
+
+	vgid = get_vgid();
+	value->u.s64 = vgid;
+}
+
+int lttng_add_vgid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vgid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vgid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vgid_get_size;
+	field->record = vgid_record;
+	field->get_value = vgid_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context-vsgid.c b/liblttng-ust/lttng-context-vsgid.c
new file mode 100644
index 0000000..9fe7c65
--- /dev/null
+++ b/liblttng-ust/lttng-context-vsgid.c
@@ -0,0 +1,129 @@
+/*
+ * lttng-context-vsgid.c
+ *
+ * LTTng UST namespaced saved set-group ID context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+/*
+ * At the kernel level, user IDs and group IDs are a per-thread attribute.
+ * However, POSIX requires that all threads in a process share the same
+ * credentials. The NPTL threading implementation handles the POSIX
+ * requirements by providing wrapper functions for the various system calls
+ * that change process UIDs and GIDs. These wrapper functions (including those
+ * for setreuid() and setregid()) employ a signal-based technique to ensure
+ * that when one thread changes credentials, all of the other threads in the
+ * process also change their credentials.
+ */
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. User / group IDs are global to the process.
+ */
+static gid_t cached_vsgid = (gid_t) -1;
+
+static
+gid_t get_vsgid(void)
+{
+	if (caa_unlikely(cached_vsgid == (gid_t) -1)) {
+		int res;
+		gid_t gid, egid, sgid;
+
+		if (getresgid(&gid, &egid, &sgid) == 0) {
+			cached_vsgid = sgid;
+		}
+	}
+
+	return cached_vsgid;
+}
+
+/*
+ * The vsgid can change on setuid, setreuid and setresuid.
+ */
+void lttng_context_vsgid_reset(void)
+{
+	cached_vsgid = (gid_t) -1;
+}
+
+static
+size_t vsgid_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(gid_t));
+	size += sizeof(gid_t);
+	return size;
+}
+
+static
+void vsgid_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	gid_t vsgid;
+
+	vsgid = get_vsgid();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(vsgid));
+	chan->ops->event_write(ctx, &vsgid, sizeof(vsgid));
+}
+
+static
+void vsgid_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	gid_t vsgid;
+
+	vsgid = get_vsgid();
+	value->u.s64 = vsgid;
+}
+
+int lttng_add_vsgid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vsgid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vsgid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vsgid_get_size;
+	field->record = vsgid_record;
+	field->get_value = vsgid_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context-vsuid.c b/liblttng-ust/lttng-context-vsuid.c
new file mode 100644
index 0000000..abdbb1c
--- /dev/null
+++ b/liblttng-ust/lttng-context-vsuid.c
@@ -0,0 +1,130 @@
+/*
+ * lttng-context-vsuid.c
+ *
+ * LTTng UST namespaced saved set-user ID context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+
+/*
+ * At the kernel level, user IDs and group IDs are a per-thread attribute.
+ * However, POSIX requires that all threads in a process share the same
+ * credentials. The NPTL threading implementation handles the POSIX
+ * requirements by providing wrapper functions for the various system calls
+ * that change process UIDs and GIDs. These wrapper functions (including those
+ * for setreuid() and setregid()) employ a signal-based technique to ensure
+ * that when one thread changes credentials, all of the other threads in the
+ * process also change their credentials.
+ */
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. User / group IDs are global to the process.
+ */
+static uid_t cached_vsuid = (uid_t) -1;
+
+static
+uid_t get_vsuid(void)
+{
+	if (caa_unlikely(cached_vsuid == (uid_t) -1)) {
+		int res;
+		uid_t uid, euid, suid;
+
+		if (getresuid(&uid, &euid, &suid) == 0) {
+			cached_vsuid = suid;
+		}
+	}
+
+	return cached_vsuid;
+}
+
+/*
+ * The vsuid can change on setuid, setreuid and setresuid.
+ */
+void lttng_context_vsuid_reset(void)
+{
+	cached_vsuid = (uid_t) -1;
+}
+
+static
+size_t vsuid_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(uid_t));
+	size += sizeof(uid_t);
+	return size;
+}
+
+static
+void vsuid_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	uid_t vsuid;
+
+	vsuid = get_vsuid();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(vsuid));
+	chan->ops->event_write(ctx, &vsuid, sizeof(vsuid));
+}
+
+static
+void vsuid_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	uid_t vsuid;
+
+	vsuid = get_vsuid();
+	value->u.s64 = vsuid;
+}
+
+int lttng_add_vsuid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vsuid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vsuid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vsuid_get_size;
+	field->record = vsuid_record;
+	field->get_value = vsuid_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context-vuid.c b/liblttng-ust/lttng-context-vuid.c
new file mode 100644
index 0000000..a9bf7b3
--- /dev/null
+++ b/liblttng-ust/lttng-context-vuid.c
@@ -0,0 +1,123 @@
+/*
+ * lttng-context-vuid.c
+ *
+ * LTTng UST namespaced real user ID context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2018 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+/*
+ * At the kernel level, user IDs and group IDs are a per-thread attribute.
+ * However, POSIX requires that all threads in a process share the same
+ * credentials. The NPTL threading implementation handles the POSIX
+ * requirements by providing wrapper functions for the various system calls
+ * that change process UIDs and GIDs. These wrapper functions (including those
+ * for setreuid() and setregid()) employ a signal-based technique to ensure
+ * that when one thread changes credentials, all of the other threads in the
+ * process also change their credentials.
+ */
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. User / group IDs are global to the process.
+ */
+static uid_t cached_vuid = (uid_t) -1;
+
+static
+uid_t get_vuid(void)
+{
+	if (caa_unlikely(cached_vuid == (uid_t) -1)) {
+		cached_vuid = getuid();
+	}
+
+	return cached_vuid;
+}
+
+/*
+ * The vuid can change on setuid, setreuid and setresuid.
+ */
+void lttng_context_vuid_reset(void)
+{
+	cached_vuid = (uid_t) -1;
+}
+
+static
+size_t vuid_get_size(struct lttng_ctx_field *field, size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, lttng_alignof(uid_t));
+	size += sizeof(uid_t);
+	return size;
+}
+
+static
+void vuid_record(struct lttng_ctx_field *field,
+		 struct lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	uid_t vuid;
+
+	vuid = get_vuid();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(vuid));
+	chan->ops->event_write(ctx, &vuid, sizeof(vuid));
+}
+
+static
+void vuid_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	uid_t vuid;
+
+	vuid = get_vuid();
+	value->u.s64 = vuid;
+}
+
+int lttng_add_vuid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vuid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vuid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vuid_get_size;
+	field->record = vuid_record;
+	field->get_value = vuid_get_value;
+	lttng_context_update(*ctx);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context.c b/liblttng-ust/lttng-context.c
index ad6c38f..e408def 100644
--- a/liblttng-ust/lttng-context.c
+++ b/liblttng-ust/lttng-context.c
@@ -407,6 +407,36 @@ int lttng_session_context_init(struct lttng_ctx **ctx)
 		WARN("Cannot add context lttng_add_uts_ns_to_ctx");
 		goto error;
 	}
+	ret = lttng_add_vuid_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_vuid_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_veuid_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_veuid_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_vsuid_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_vsuid_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_vgid_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_vgid_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_vegid_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_vegid_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_vsgid_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_vsgid_to_ctx");
+		goto error;
+	}
 	lttng_context_update(*ctx);
 	return 0;
 
diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c
index 329aae0..55f854f 100644
--- a/liblttng-ust/lttng-events.c
+++ b/liblttng-ust/lttng-events.c
@@ -1126,6 +1126,18 @@ int lttng_attach_context(struct lttng_ust_context *context_param,
 		return lttng_add_user_ns_to_ctx(ctx);
 	case LTTNG_UST_CONTEXT_UTS_NS:
 		return lttng_add_uts_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_VUID:
+		return lttng_add_vuid_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_VEUID:
+		return lttng_add_veuid_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_VSUID:
+		return lttng_add_vsuid_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_VGID:
+		return lttng_add_vgid_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_VEGID:
+		return lttng_add_vegid_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_VSGID:
+		return lttng_add_vsgid_to_ctx(ctx);
 	default:
 		return -EINVAL;
 	}
diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c
index eda4904..94bd35f 100644
--- a/liblttng-ust/lttng-ust-comm.c
+++ b/liblttng-ust/lttng-ust-comm.c
@@ -1954,6 +1954,22 @@ void ust_context_ns_reset(void)
 	lttng_context_uts_ns_reset();
 }
 
+static
+void ust_context_vuids_reset(void)
+{
+	lttng_context_vuid_reset();
+	lttng_context_veuid_reset();
+	lttng_context_vsuid_reset();
+}
+
+static
+void ust_context_vgids_reset(void)
+{
+	lttng_context_vgid_reset();
+	lttng_context_vegid_reset();
+	lttng_context_vsgid_reset();
+}
+
 /*
  * We exclude the worker threads across fork and clone (except
  * CLONE_VM), because these system calls only keep the forking thread
@@ -2032,6 +2048,8 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 	lttng_context_vpid_reset();
 	lttng_context_vtid_reset();
 	ust_context_ns_reset();
+	ust_context_vuids_reset();
+	ust_context_vgids_reset();
 	DBG("process %d", getpid());
 	/* Release urcu mutexes */
 	rcu_bp_after_fork_child();
@@ -2044,11 +2062,55 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 void ust_after_setns(void)
 {
 	ust_context_ns_reset();
+	ust_context_vuids_reset();
+	ust_context_vgids_reset();
 }
 
 void ust_after_unshare(void)
 {
 	ust_context_ns_reset();
+	ust_context_vuids_reset();
+	ust_context_vgids_reset();
+}
+
+void ust_after_setuid(void)
+{
+	ust_context_vuids_reset();
+}
+
+void ust_after_seteuid(void)
+{
+	ust_context_vuids_reset();
+}
+
+void ust_after_setreuid(void)
+{
+	ust_context_vuids_reset();
+}
+
+void ust_after_setresuid(void)
+{
+	ust_context_vuids_reset();
+}
+
+void ust_after_setgid(void)
+{
+	ust_context_vgids_reset();
+}
+
+void ust_after_setegid(void)
+{
+	ust_context_vgids_reset();
+}
+
+void ust_after_setregid(void)
+{
+	ust_context_vgids_reset();
+}
+
+void ust_after_setresgid(void)
+{
+	ust_context_vgids_reset();
 }
 
 void lttng_ust_sockinfo_session_enabled(void *owner)
-- 
2.7.4

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-03-06 20:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1520369615-10782-1-git-send-email-mjeanson@efficios.com>
2018-03-06 20:53 ` [PATCH lttng-ust 1/2] RFC: Add userspace namespace contexts Michael Jeanson
2018-03-06 20:53 ` [PATCH lttng-ust 2/2] RFC: Add userspace vuid/vgid contexts Michael Jeanson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.