From f753dd62f951cc62e164421d0c6491f39e4c68ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Fri, 7 Jun 2013 11:55:27 +0200 Subject: [PATCH] udev: fix crash in libudev logging Call virLogVMessage instead of virLogMessage, since libudev called us with a va_list object, not a list of arguments. Honor message priority and strip the trailing newline. https://bugzilla.redhat.com/show_bug.cgi?id=969152 --- src/libvirt_private.syms | 2 ++ src/node_device/node_device_udev.c | 41 +++++++++++++++++++++++------- src/util/virlog.c | 25 ++++++++++++++++++ src/util/virlog.h | 1 + 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 042081fdb4..ee517c13a1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1480,12 +1480,14 @@ virLogMessage; virLogParseDefaultPriority; virLogParseFilters; virLogParseOutputs; +virLogPriorityFromSyslog; virLogProbablyLogMessage; virLogReset; virLogSetBufferSize; virLogSetDefaultPriority; virLogSetFromEnv; virLogUnlock; +virLogVMessage; # util/virmacaddr.h diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 620cd5823e..bb584155fd 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -348,15 +348,37 @@ static int udevGenerateDeviceName(struct udev_device *device, } -static void udevLogFunction(struct udev *udev ATTRIBUTE_UNUSED, - int priority ATTRIBUTE_UNUSED, - const char *file, - int line, - const char *fn, - const char *fmt, - va_list args) +typedef void (*udevLogFunctionPtr)(struct udev *udev, + int priority, + const char *file, + int line, + const char *fn, + const char *format, + va_list args); + +static void +ATTRIBUTE_FMT_PRINTF(6,0) +udevLogFunction(struct udev *udev ATTRIBUTE_UNUSED, + int priority, + const char *file, + int line, + const char *fn, + const char *fmt, + va_list args) { - VIR_ERROR_INT(VIR_LOG_FROM_LIBRARY, file, line, fn, fmt, args); + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *format = NULL; + + virBufferAdd(&buf, fmt, -1); + virBufferTrim(&buf, "\n", -1); + + format = virBufferContentAndReset(&buf); + + virLogVMessage(VIR_LOG_FROM_LIBRARY, + virLogPriorityFromSyslog(priority), + file, line, fn, NULL, format ? format : fmt, args); + + VIR_FREE(format); } @@ -1672,7 +1694,8 @@ static int nodeStateInitialize(bool privileged ATTRIBUTE_UNUSED, * its return value. */ udev = udev_new(); - udev_set_log_fn(udev, udevLogFunction); + /* cast to get rid of missing-format-attribute warning */ + udev_set_log_fn(udev, (udevLogFunctionPtr) udevLogFunction); priv->udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); if (priv->udev_monitor == NULL) { diff --git a/src/util/virlog.c b/src/util/virlog.c index 739a27476a..064f8e8c30 100644 --- a/src/util/virlog.c +++ b/src/util/virlog.c @@ -1264,6 +1264,31 @@ static int virLogAddOutputToJournald(int priority) return 0; } # endif /* USE_JOURNALD */ + +int virLogPriorityFromSyslog(int priority) +{ + switch (priority) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + return VIR_LOG_ERROR; + case LOG_WARNING: + case LOG_NOTICE: + return VIR_LOG_WARN; + case LOG_INFO: + return VIR_LOG_INFO; + case LOG_DEBUG: + return VIR_LOG_DEBUG; + } + return VIR_LOG_ERROR; +} + +#else /* HAVE_SYSLOG_H */ +int virLogPriorityFromSyslog(int priority ATTRIBUTE_UNUSED) +{ + return VIR_LOG_ERROR; +} #endif /* HAVE_SYSLOG_H */ #define IS_SPACE(cur) \ diff --git a/src/util/virlog.h b/src/util/virlog.h index 6b83245ece..7db1657157 100644 --- a/src/util/virlog.h +++ b/src/util/virlog.h @@ -171,6 +171,7 @@ extern int virLogReset(void); extern int virLogParseDefaultPriority(const char *priority); extern int virLogParseFilters(const char *filters); extern int virLogParseOutputs(const char *output); +extern int virLogPriorityFromSyslog(int priority); extern void virLogMessage(virLogSource src, virLogPriority priority, const char *filename,