From: Zbigniew Jędrzejewski-Szmek Date: Fri, 7 Oct 2022 13:56:25 +0000 (+0200) Subject: sd-bus: make bus_error_message() a thread-safe macro X-Git-Tag: v252-rc2~70^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eaaf7465ee6afd621df639f583b5affebd306e9c;p=thirdparty%2Fsystemd.git sd-bus: make bus_error_message() a thread-safe macro strerror_r() is used instead of strerror(). The usual trick is employed: we allocate a buffer that lives until the end of the surrounding block to provide the scratch space. This change is particularly important forn sd-bus and the pam modules, which may be called from threaded code. I checked the codebase, and we only use bus_error_message() in log statements, so the returned pointer is not used beyond its valid lifetime. --- diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index aca3ac36d2c..4d687cfac9e 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -494,7 +494,7 @@ _public_ int sd_bus_error_set_errno(sd_bus_error *e, int error) { *e = BUS_ERROR_FAILED; } - /* Now, fill in the message from strerror() if we can */ + /* Now, fill in the message from strerror_r() if we can */ bus_error_strerror(e, error); return -error; } @@ -555,7 +555,7 @@ _public_ int sd_bus_error_set_errnofv(sd_bus_error *e, int error, const char *fo } fail: - /* If that didn't work, use strerror() for the message */ + /* If that didn't work, use strerror_r() for the message */ bus_error_strerror(e, error); return -error; } @@ -586,7 +586,7 @@ _public_ int sd_bus_error_set_errnof(sd_bus_error *e, int error, const char *for return sd_bus_error_set_errno(e, error); } -const char *bus_error_message(const sd_bus_error *e, int error) { +const char* _bus_error_message(const sd_bus_error *e, int error, char buf[static ERRNO_BUF_LEN]) { /* Sometimes, the D-Bus server is a little bit too verbose with * its error messages, so let's override them here */ if (sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED)) @@ -595,7 +595,7 @@ const char *bus_error_message(const sd_bus_error *e, int error) { if (e && e->message) return e->message; - return strerror_safe(error); + return strerror_r(abs(error), buf, ERRNO_BUF_LEN); } static bool map_ok(const sd_bus_error_map *map) { diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h index 518493762c8..c8768c9a7b6 100644 --- a/src/libsystemd/sd-bus/bus-error.h +++ b/src/libsystemd/sd-bus/bus-error.h @@ -5,11 +5,17 @@ #include "sd-bus.h" +#include "errno-util.h" #include "macro.h" bool bus_error_is_dirty(sd_bus_error *e); -const char *bus_error_message(const sd_bus_error *e, int error); +const char* _bus_error_message(const sd_bus_error *e, int error, char buf[static ERRNO_BUF_LEN]); + +/* Note: the lifetime of the compound literal is the immediately surrounding block, + * see C11 §6.5.2.5, and + * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */ +#define bus_error_message(e, error) _bus_error_message(e, error, (char[ERRNO_BUF_LEN]){}) #define BUS_ERROR_OOM SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_MEMORY, "Out of memory") #define BUS_ERROR_FAILED SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FAILED, "Operation failed")