#1111781 electric-fence: incorrect usage of strerror_r()

Package:
electric-fence
Source:
electric-fence
Description:
A malloc(3) debugger
Submitter:
Chris Packham
Date:
2025-10-05 20:17:01 UTC
Severity:
normal
#1111781#5
Date:
2025-08-21 20:36:00 UTC
From:
To:
Dear Maintainer,

This is a follow up to #1074933. The fix for the ftbfs was to add a cast

diff -Naurp electric-fence_2.2.6/page.c electric-fence_2.2.7/page.c
--- electric-fence_2.2.6/page.c 2021-11-13 07:58:14.000000000 +1300
+++ electric-fence_2.2.7/page.c 2024-08-21 03:52:57.000000000 +1200
@@ -43,7 +43,7 @@ stringErrorReport(void)
 #elif ( defined(_AIX) )
        return strerror(errno);
 #else
-       return strerror_r(errno,(char *)err_message,128);
+       return (const char *) strerror_r(errno,(char *)err_message,128);
 #endif
 }

But according to strerror(3) there are two possible implementations of strerror_r().

       int strerror_r(int errnum, char *buf, size_t buflen);
                   /* XSI-compliant */

       char *strerror_r(int errnum, char *buf, size_t buflen);
                   /* GNU-specific */

       strerror_r():
           The XSI-compliant version is provided if:
           (_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE
           Otherwise, the GNU-specific version is provided.

GCC-14 now has _POSIX_C_SOURCE set to something higher than 200112L so we
appear to be getting the XSI compliant version of strerror_r() so simply adding
a cast is insufficient (and may lead to a null deference by the caller of
stringErrorReport()). This probably needs to be written as

static char err_message[128];
strerror_r(errno, err_message,128);
return err_message;

Or something should define _GNU_SOURCE to get the old behaviour.

#1111781#10
Date:
2025-10-05 11:03:23 UTC
From:
To:
Hi,

Thanks for the detailed bug report.

I think you're right that the fix to 1074933 was incorrect, but I wonder
whether we should behave differently based on the feature test macros
that are set (i.e. that efence should be able to cope with either
version of strerror_r)? so something like

#if (_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE/* expect int return
*/#else
/* expect char * return */#endif?

Regards,

Matthew

#1111781#15
Date:
2025-10-05 20:06:22 UTC
From:
To:
I do wonder if using strerror_r() is making things harder than it needs
to be. It seems to be making stringErrorReport() non re-entrant anyway
so why not just use strerror() and avoid the conflicting definitions of
strerror_r() completely.