mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-13 12:58:20 +03:00
log: fix repeated invocation of vsnprintf()/vaprintf() in log_struct()
https://bugs.freedesktop.org/show_bug.cgi?id=55213
This commit is contained in:
parent
1920e37ef9
commit
963ddb917d
@ -1307,6 +1307,12 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (arg_user) {
|
||||
|
||||
/* Note that this resolves user names
|
||||
* inside the container, and hence
|
||||
* accesses the NSS modules from the
|
||||
* container and not the host. This is
|
||||
* a bit weird... */
|
||||
|
||||
if (get_user_creds((const char**)&arg_user, &uid, &gid, &home, NULL) < 0) {
|
||||
log_error("get_user_creds() failed: %m");
|
||||
goto child_fail;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stddef.h>
|
||||
#include <printf.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
@ -705,11 +706,23 @@ int log_struct_internal(
|
||||
va_start(ap, format);
|
||||
while (format && n + 1 < ELEMENTSOF(iovec)) {
|
||||
char *buf;
|
||||
va_list aq;
|
||||
|
||||
if (vasprintf(&buf, format, ap) < 0) {
|
||||
/* We need to copy the va_list structure,
|
||||
* since vasprintf() leaves it afterwards at
|
||||
* an undefined location */
|
||||
|
||||
va_copy(aq, ap);
|
||||
if (vasprintf(&buf, format, aq) < 0) {
|
||||
va_end(aq);
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
va_end(aq);
|
||||
|
||||
/* Now, jump enough ahead, so that we point to
|
||||
* the next format string */
|
||||
VA_FORMAT_ADVANCE(format, ap);
|
||||
|
||||
IOVEC_SET_STRING(iovec[n++], buf);
|
||||
|
||||
@ -742,8 +755,11 @@ int log_struct_internal(
|
||||
|
||||
va_start(ap, format);
|
||||
while (format) {
|
||||
va_list aq;
|
||||
|
||||
vsnprintf(buf, sizeof(buf), format, ap);
|
||||
va_copy(aq, ap);
|
||||
vsnprintf(buf, sizeof(buf), format, aq);
|
||||
va_end(aq);
|
||||
char_array_0(buf);
|
||||
|
||||
if (startswith(buf, "MESSAGE=")) {
|
||||
@ -751,6 +767,8 @@ int log_struct_internal(
|
||||
break;
|
||||
}
|
||||
|
||||
VA_FORMAT_ADVANCE(format, ap);
|
||||
|
||||
format = va_arg(ap, char *);
|
||||
}
|
||||
va_end(ap);
|
||||
|
@ -193,4 +193,47 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
|
||||
#define _cleanup_closedir_ __attribute__((cleanup(closedirp)))
|
||||
#define _cleanup_umask_ __attribute__((cleanup(umaskp)))
|
||||
|
||||
#define VA_FORMAT_ADVANCE(format, ap) do { \
|
||||
int _argtypes[64]; \
|
||||
size_t _i, _k; \
|
||||
_k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
|
||||
for (_i = 0; _i < _k; _i++) { \
|
||||
if (_argtypes[_i] & PA_FLAG_PTR) { \
|
||||
(void) va_arg(ap, void*); \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
switch (_argtypes[_i]) { \
|
||||
case PA_INT: \
|
||||
case PA_INT|PA_FLAG_SHORT: \
|
||||
case PA_CHAR: \
|
||||
(void) va_arg(ap, int); \
|
||||
break; \
|
||||
case PA_INT|PA_FLAG_LONG: \
|
||||
(void) va_arg(ap, long int); \
|
||||
break; \
|
||||
case PA_INT|PA_FLAG_LONG_LONG: \
|
||||
(void) va_arg(ap, long long int); \
|
||||
break; \
|
||||
case PA_WCHAR: \
|
||||
(void) va_arg(ap, wchar_t); \
|
||||
break; \
|
||||
case PA_WSTRING: \
|
||||
case PA_STRING: \
|
||||
case PA_POINTER: \
|
||||
(void) va_arg(ap, void*); \
|
||||
break; \
|
||||
case PA_FLOAT: \
|
||||
case PA_DOUBLE: \
|
||||
(void) va_arg(ap, double); \
|
||||
break; \
|
||||
case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
|
||||
(void) va_arg(ap, long double); \
|
||||
break; \
|
||||
default: \
|
||||
assert_not_reached("Unknown format string argument."); \
|
||||
} \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
#include "log.h"
|
||||
|
@ -42,5 +42,12 @@ int main(int argc, char* argv[]) {
|
||||
"SERVICE=foobar",
|
||||
NULL);
|
||||
|
||||
log_struct(LOG_INFO,
|
||||
"MESSAGE=Foobar PID=%lu", (unsigned long) getpid(),
|
||||
"FORMAT_STR_TEST=1=%i A=%c 2=%hi 3=%li 4=%lli 1=%p foo=%s 2.5=%g 3.5=%g 4.5=%Lg",
|
||||
(int) 1, 'A', (short) 2, (long int) 3, (long long int) 4, (void*) 1, "foo", (float) 2.5f, (double) 3.5, (long double) 4.5,
|
||||
"SUFFIX=GOT IT",
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user