fix: handle EINTR correctly in get_cpu_mask_from_sysfs
[lttng-ust.git] / src / common / getenv.c
CommitLineData
6f626d28 1/*
c0c0989a 2 * SPDX-License-Identifier: LGPL-2.1-only
6f626d28 3 *
c0c0989a 4 * Copyright (C) 2017 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6f626d28
MD
5 */
6
7#include <stdlib.h>
8#include <unistd.h>
9#include <stdbool.h>
b4051ad8 10#include <stddef.h>
6f626d28 11#include <sys/types.h>
042dbbc8 12#include <pthread.h>
910dcd72 13#include <urcu/system.h>
9d315d6d
MJ
14#include "common/logging.h"
15#include "common/macros.h"
910dcd72 16#include "common/getenv.h"
6f626d28
MD
17
18enum lttng_env_secure {
19 LTTNG_ENV_SECURE,
20 LTTNG_ENV_NOT_SECURE,
21};
22
23struct lttng_env {
24 const char *key;
25 enum lttng_env_secure secure;
26 char *value;
27};
28
042dbbc8
MD
29/* lttng_ust_getenv_init_mutex provides mutual exclusion for initialization. */
30static pthread_mutex_t lttng_ust_getenv_init_mutex = PTHREAD_MUTEX_INITIALIZER;
31static int lttng_ust_getenv_is_init = 0;
910dcd72 32
6f626d28
MD
33static struct lttng_env lttng_env[] = {
34 /*
9ff107a9
MJ
35 * LTTNG_UST_DEBUG and LTTNG_UST_ABORT_ON_CRITICAL are used directly by
36 * the internal logging, because they need to be already set for ERR()
37 * used in lttng_ust_getenv_init().
6f626d28
MD
38 */
39 { "LTTNG_UST_DEBUG", LTTNG_ENV_NOT_SECURE, NULL, },
9ff107a9 40 { "LTTNG_UST_ABORT_ON_CRITICAL", LTTNG_ENV_NOT_SECURE, NULL, },
6f626d28
MD
41
42 /* Env. var. which can be used in setuid/setgid executables. */
43 { "LTTNG_UST_WITHOUT_BADDR_STATEDUMP", LTTNG_ENV_NOT_SECURE, NULL, },
44 { "LTTNG_UST_REGISTER_TIMEOUT", LTTNG_ENV_NOT_SECURE, NULL, },
97572c04 45 { "LTTNG_UST_MAP_POPULATE_POLICY", LTTNG_ENV_NOT_SECURE, NULL, },
6f626d28
MD
46
47 /* Env. var. which are not fetched in setuid/setgid executables. */
48 { "LTTNG_UST_CLOCK_PLUGIN", LTTNG_ENV_SECURE, NULL, },
49 { "LTTNG_UST_GETCPU_PLUGIN", LTTNG_ENV_SECURE, NULL, },
b2c5f61a 50 { "LTTNG_UST_ALLOW_BLOCKING", LTTNG_ENV_SECURE, NULL, },
6f626d28
MD
51 { "HOME", LTTNG_ENV_SECURE, NULL, },
52 { "LTTNG_HOME", LTTNG_ENV_SECURE, NULL, },
c0f6fb05 53 { "LTTNG_UST_APP_PATH", LTTNG_ENV_SECURE, NULL, },
6f626d28
MD
54};
55
56static
57int lttng_is_setuid_setgid(void)
58{
59 return geteuid() != getuid() || getegid() != getgid();
60}
61
910dcd72
MJ
62/*
63 * Wrapper over getenv that will only return the values of whitelisted
64 * environment variables when the current process is setuid and/or setgid.
65 */
4c41b460 66char *lttng_ust_getenv(const char *name)
6f626d28
MD
67{
68 size_t i;
69 struct lttng_env *e;
70 bool found = false;
71
407937dc
MD
72 /*
73 * Perform lazy initialization of lttng_ust_getenv for early use
74 * by library constructors.
75 */
76 lttng_ust_getenv_init();
910dcd72 77
6f626d28
MD
78 for (i = 0; i < LTTNG_ARRAY_SIZE(lttng_env); i++) {
79 e = &lttng_env[i];
80
81 if (strcmp(e->key, name) == 0) {
82 found = true;
83 break;
84 }
85 }
86 if (!found) {
87 return NULL;
88 }
89 return e->value;
90}
91
92void lttng_ust_getenv_init(void)
93{
94 size_t i;
95
042dbbc8
MD
96 /*
97 * Return early if the init has already completed.
98 */
99 if (CMM_LOAD_SHARED(lttng_ust_getenv_is_init)) {
100 /*
101 * Load lttng_ust_getenv_is_init before reading environment cache.
102 */
103 cmm_smp_rmb();
910dcd72 104 return;
042dbbc8
MD
105 }
106
107 pthread_mutex_lock(&lttng_ust_getenv_init_mutex);
108
109 /*
110 * Check again if the init has completed in another thread now that we
111 * have acquired the mutex.
112 */
113 if (lttng_ust_getenv_is_init)
114 goto end_init;
910dcd72 115
6f626d28
MD
116 for (i = 0; i < LTTNG_ARRAY_SIZE(lttng_env); i++) {
117 struct lttng_env *e = &lttng_env[i];
118
119 if (e->secure == LTTNG_ENV_SECURE && lttng_is_setuid_setgid()) {
120 ERR("Getting environment variable '%s' from setuid/setgid binary refused for security reasons.",
121 e->key);
122 continue;
123 }
124 e->value = getenv(e->key);
125 }
042dbbc8
MD
126
127 /*
128 * Store environment cache before setting lttng_ust_getenv_is_init to 1.
129 */
130 cmm_smp_wmb();
910dcd72 131 CMM_STORE_SHARED(lttng_ust_getenv_is_init, 1);
042dbbc8
MD
132end_init:
133 pthread_mutex_unlock(&lttng_ust_getenv_init_mutex);
6f626d28 134}
This page took 0.03811 seconds and 4 git commands to generate.