]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: make bus_error_message() a thread-safe macro
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 7 Oct 2022 13:56:25 +0000 (15:56 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 11 Oct 2022 14:59:00 +0000 (16:59 +0200)
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.

src/libsystemd/sd-bus/bus-error.c
src/libsystemd/sd-bus/bus-error.h

index aca3ac36d2c281073c7aa71399ca59070b8d7553..4d687cfac9e987a6abf08a6ce9bf75ae588f275a 100644 (file)
@@ -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) {
index 518493762c8f675750ebebf3b93461d19d4dc6c8..c8768c9a7b61278a78c6762352798e004b0810cb 100644 (file)
@@ -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")