[PATCH] debug: State buffer overflow message more precisely

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Thu Jul 11 14:34:45 GMT 2024



On 07/07/24 13:23, Ingo Blechschmidt wrote:
> This patch contributes to our source fortification endeavors by
> slightly rewording the error message on detecting a probable buffer
> overflow. The new error message adds a bit of nuance, helping to
> demarcate the efforts of source fortification from an unmitigated
> actual buffer overflow, thereby describing the situation more precisely,
> preventing misunderstandings and highlighting source fortification.
> 
> I ran into this issue when debugging a problem with Privoxy
> (https://github.com/NixOS/nixpkgs/issues/265654). Source fortification
> correctly identified a libc call which was potentially problematic and
> (in my view) misleading, but actually safe. A more precise error
> message, as proposed by this patch, would have sped up the diagnosis.

>From the bug report, the code does seems to be issuing UB and compiler itself
warns about. With a reduced testcase:

---
$ cat t.c
#define _GNU_SOURCE
#include <string.h>

#define BUFFER_SIZE 5000

static const char socks_userid[] = "anonymous";

struct socks_op {
   unsigned char vn;          /* socks version number */
   unsigned char cd;          /* command code */
   unsigned char dstport[2];  /* destination port */
   unsigned char dstip[4];    /* destination address */
   char userid;               /* first byte of userid */
   char padding[3];           /* make sure sizeof(struct socks_op) is endian-independent. */
   /* more bytes of the userid follow, terminated by a NULL */
};

void foo (void)
{
  char buf[BUFFER_SIZE];
  struct socks_op    *c = (struct socks_op    *)buf;
  strlcpy(&(c->userid), socks_userid, sizeof(buf) - sizeof(struct socks_op));
}
$ gcc -Wall t.c -c -O2 -D_FORTIFY_SOURCE=2
t.c: In function ‘foo’:
t.c:22:3: warning: ‘strlcpy’ writing 4988 bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
   22 |   strlcpy(&(c->userid), socks_userid, sizeof(buf) - sizeof(struct socks_op));
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.c:13:9: note: destination object ‘userid’ of size 1
   13 |    char userid;               /* first byte of userid */
      |         ^~~~~~
In file included from /usr/include/features.h:502,
                 from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33,
                 from /usr/include/string.h:26,
                 from t.c:2:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:150:1: note: in a call to function ‘strlcpy’ declared with attribute ‘access (write_only, 1, 3)’
  150 | __NTH (strlcpy (char *__restrict __dest, const char *__restrict __src,
      | ^~~~~
---

And I don't think changing the error message improves anything here,
if __chk_fail is called the program will be terminated anyway.  If you
think this is a false-positive, we will need to check whether the compiler
expansion for the strlcpy is being correct (meaning that __glibc_objsize
is passing the expected values), not to paper over the log.

> ---
>  debug/chk_fail.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/debug/chk_fail.c b/debug/chk_fail.c
> index 77d54c6706..44f367deec 100644
> --- a/debug/chk_fail.c
> +++ b/debug/chk_fail.c
> @@ -25,6 +25,6 @@ void
>  __attribute__ ((noreturn))
>  __chk_fail (void)
>  {
> -  __fortify_fail ("buffer overflow detected");
> +  __fortify_fail ("probable buffer overflow detected");
>  }
>  libc_hidden_def (__chk_fail)


More information about the Libc-alpha mailing list