Mailing List Archive

Guarantees of gpg_strerror_r may not hold
Hi,

From inspecting the gpgrt source code, it seems that for system error
codes and on systems with POSIX-conforming strerror_r, gpg_strerror_r
calls out to strerror_r and, since strerror_r is not guaranteed to, null
terminates the buffer.

However, POSIX doesn't say that a partial error message will have been
written if strerror_r fails with ERANGE, and strerror_r is also allowed
to fail with other errors besides EINVAL and ERANGE. That means that if
the caller didn't initialize their buffer, there is a risk of their
buffer starting with uninitialized memory, something the GPGME docs say
won't happen.

I propose that if strerror_r fails, we should do the equivalent of
snprintf(buf, bufsize, "GPG error %u\n", errcode);
to populate the caller's buffer.
Re: Guarantees of gpg_strerror_r may not hold [ In reply to ]
Hello,

John Scott via Gnupg-devel <gnupg-devel@gnupg.org> wrote:
> That means that if the caller didn't initialize their buffer, there is
> a risk of their buffer starting with uninitialized memory, something
> the GPGME docs say won't happen.

Thank you for your suggestion.

To be consistent to other parts of the code, something like this is more
appropriate, I suppose.

==========================
diff --git a/src/strerror.c b/src/strerror.c
index fb1bebf..51e57d8 100644
--- a/src/strerror.c
+++ b/src/strerror.c
@@ -96,7 +96,21 @@ system_strerror_r (int no, char *buf, size_t buflen)
static int
system_strerror_r (int no, char *buf, size_t buflen)
{
- return strerror_r (no, buf, buflen);
+ int saved_errno;
+ int r = strerror_r (no, buf, buflen);
+
+ if (r)
+ {
+ if (r < 0)
+ saved_errno = errno;
+ else
+ saved_errno = r;
+
+ snprintf (buf, buflen, "strerror_r failed: %i\n", r);
+ return saved_errno;
+ }
+
+ return 0;
}

#endif /* STRERROR_R_CHAR_P */
--

_______________________________________________
Gnupg-devel mailing list
Gnupg-devel@gnupg.org
https://lists.gnupg.org/mailman/listinfo/gnupg-devel
Re: Guarantees of gpg_strerror_r may not hold [ In reply to ]
On Wed, 30 Nov 2022 12:38, NIIBE Yutaka said:

> + snprintf (buf, buflen, "strerror_r failed: %i\n", r);

May I suggest to use

snprintf (buf, buflen, "[errno=%i]\n", r);

Sich bracketed error messages are often used if there is a problem wit
the error message.


Salam-Shalom,

Werner

--
The pioneers of a warless world are the youth that
refuse military service. - A. Einstein