secure_getenv does not work when the process has a nonempty permitted
capability set, which means that it's unduly hard to configure logging in
elogind-logind, elogind-resolved, and others.
secure_getenv is useful for code in libraries which might get called from a
setuid application. log_parse_environment() is never called from our library
code, but directly form various top-level executables. None of them are
installed suid, and none are prepared to be used this way, since many
additional changes would be required to make that safe. We may just as well
drop the check and allow SYSTEMD_LOG_* to properly parsed.
Fixes #4900.
#define SNDBUF_SIZE (8*1024*1024)
static LogTarget log_target = LOG_TARGET_CONSOLE;
#define SNDBUF_SIZE (8*1024*1024)
static LogTarget log_target = LOG_TARGET_CONSOLE;
-static int log_max_level = LOG_INFO;
+static int log_max_level[] = {LOG_INFO, LOG_INFO};
+assert_cc(ELEMENTSOF(log_max_level) == _LOG_REALM_MAX);
static int log_facility = LOG_DAEMON;
static int console_fd = STDERR_FILENO;
static int log_facility = LOG_DAEMON;
static int console_fd = STDERR_FILENO;
-void log_set_max_level(int level) {
+void log_set_max_level_realm(LogRealm realm, int level) {
assert((level & LOG_PRIMASK) == level);
assert((level & LOG_PRIMASK) == level);
+ assert(realm < ELEMENTSOF(log_max_level));
+ log_max_level[realm] = level;
}
void log_set_facility(int facility) {
}
void log_set_facility(int facility) {
- int level,
- int error,
- const char *file,
- int line,
- const char *func,
- char *buffer) {
+ int level,
+ int error,
+ const char *file,
+ int line,
+ const char *func,
+ char *buffer) {
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
PROTECT_ERRNO;
/* This modifies the buffer... */
PROTECT_ERRNO;
/* This modifies the buffer... */
if (error < 0)
error = -error;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
return -error;
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
+int log_internalv_realm(
int level,
int error,
const char *file,
int level,
int error,
const char *file,
const char *format,
va_list ap) {
const char *format,
va_list ap) {
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
if (error < 0)
error = -error;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
/* Make sure that %m maps to the specified error */
return -error;
/* Make sure that %m maps to the specified error */
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
int level,
int error,
const char *file,
int level,
int error,
const char *file,
int r;
va_start(ap, format);
int r;
va_start(ap, format);
- r = log_internalv(level, error, file, line, func, format, ap);
+ r = log_internalv_realm(level, error, file, line, func, format, ap);
if (error < 0)
error = -error;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
return -error;
/* Make sure that %m maps to the specified error */
return -error;
/* Make sure that %m maps to the specified error */
const char *format) {
static char buffer[LINE_MAX];
const char *format) {
static char buffer[LINE_MAX];
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return;
DISABLE_WARNING_FORMAT_NONLITERAL;
return;
DISABLE_WARNING_FORMAT_NONLITERAL;
log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
-noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
- log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+ "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
-noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
- log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_unreachable_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+ "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
-void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
+void log_assert_failed_return_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
- log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
+ "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
-int log_oom_internal(const char *file, int line, const char *func) {
- log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
+int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
+ log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
+ ENOMEM, file, line, func, "Out of memory.");
char buf[LINE_MAX];
bool found = false;
char buf[LINE_MAX];
bool found = false;
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
PROTECT_ERRNO;
va_list ap;
if (error < 0)
error = -error;
PROTECT_ERRNO;
va_list ap;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
if (log_target == LOG_TARGET_NULL)
return -error;
if (log_target == LOG_TARGET_NULL)
-int log_set_max_level_from_string(const char *e) {
+int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
int t;
t = log_level_from_string(e);
if (t < 0)
return -EINVAL;
int t;
t = log_level_from_string(e);
if (t < 0)
return -EINVAL;
+ log_set_max_level_realm(realm, t);
-void log_parse_environment(void) {
+void log_parse_environment_realm(LogRealm realm) {
const char *e;
if (get_ctty_devnr(0, NULL) < 0)
const char *e;
if (get_ctty_devnr(0, NULL) < 0)
user stuff. */
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
user stuff. */
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
- e = secure_getenv("SYSTEMD_LOG_TARGET");
+ e = getenv("SYSTEMD_LOG_TARGET");
if (e && log_set_target_from_string(e) < 0)
log_warning("Failed to parse log target '%s'. Ignoring.", e);
if (e && log_set_target_from_string(e) < 0)
log_warning("Failed to parse log target '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_LEVEL");
- if (e && log_set_max_level_from_string(e) < 0)
+ e = getenv("SYSTEMD_LOG_LEVEL");
+ if (e && log_set_max_level_from_string_realm(realm, e) < 0)
log_warning("Failed to parse log level '%s'. Ignoring.", e);
log_warning("Failed to parse log level '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_COLOR");
+ e = getenv("SYSTEMD_LOG_COLOR");
if (e && log_show_color_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
if (e && log_show_color_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_LOCATION");
+ e = getenv("SYSTEMD_LOG_LOCATION");
if (e && log_show_location_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
}
if (e && log_show_location_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
}
-int log_get_max_level(void) {
- return log_max_level;
+int log_get_max_level_realm(LogRealm realm) {
+ return log_max_level[realm];
}
void log_show_color(bool b) {
}
void log_show_color(bool b) {
if (error < 0)
error = -error;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
return -error;
if (log_target == LOG_TARGET_NULL)
return -error;
if (log_target == LOG_TARGET_NULL)
unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
return log_struct_internal(
unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
return log_struct_internal(
+ LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
+ error,
file, line, func,
"MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
"CONFIG_FILE=%s", config_file,
file, line, func,
"MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
"CONFIG_FILE=%s", config_file,