[Bug 2011326] Re: glibc 2.37: snprintf() on armhf wrongly truncates writes given extremely large size argument

Simon Chopin 2011326 at bugs.launchpad.net
Wed Mar 15 10:25:04 UTC 2023


A related bug is that one:
https://bugs.launchpad.net/ubuntu/+source/notcurses/+bug/2008108

I've raised the issue upstream: https://sourceware.org/pipermail/libc-
alpha/2023-March/146343.html

Note that even though I technically asked the question "should we fix
it?", my personal conviction is that it's not worth it. The issue
triggers whenever the given size overflows the address space, which
happens there because stack addressed are around 0xffxxxxxx in 32-bit
architectures, so INT_MAX would overflow. Switch the buffer to a heap-
allocated one, and the issue disappears.

You can reproduce it on other architectures by substituting INT_MAX with
~(size_t)buf+1, which should overflow the address space by 1.

IMHO both the notcurses and cyrus-imapd authors are abusing the API in a
way that's just broken and doesn't actually translate the (apparent)
intent, which is to say "just write as far as you can". Which would of
course be better served by simply using sprintf.

The code responsible for the truncature is there:
https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/vsnprintf.c;h=aab32aa9e7a35745713875b7fdfafbefcb31632c;hb=9e2ff880f3cbc0b4ec8505ad2ce4a1c92d7f6d56#l85

-- 
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to glibc in Ubuntu.
https://bugs.launchpad.net/bugs/2011326

Title:
  glibc 2.37: snprintf() on armhf wrongly truncates writes given
  extremely large size argument

Status in glibc package in Ubuntu:
  Triaged

Bug description:
  The cyrus-imapd package fails to build from source on armhf in lunar
  against glibc 2.37.  I've tracked this down to a combination of bad
  string handling in the cyrus library's API, and a regression in glibc
  2.37 vs 2.36 when snprintf() is passed a size argument whose value is
  very close to INT_MAX.

  Basically, since the API is passed a buffer of unknown size, and then
  passes this on to functions that DO safe handling of buffer lengths,
  it claims a buffer size of INT_MAX.  Because the functions start
  filling the buffer before the call to snprintf(), the actual size
  argument to snprintf() is slightly less than INT_MAX.  This is
  unrealistic and incorrect, but technically valid, so snprintf() should
  handle it correctly.

  Below is a reproducer that demonstrates the bug on armhf.

  #include <limits.h>
  #include <stdio.h>
  #include <string.h>

  int main() {

      char buf[32];
      int res;

      res = snprintf(buf, sizeof(buf)-1, "%s", "hello world");

      printf("having a normal one. res=%d,buf=%s\n",res,buf);

      res = snprintf(buf, INT_MAX, "%s", "hello world");

      printf("res=%d but buf=%s\n",res,buf);
  }

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/2011326/+subscriptions




More information about the foundations-bugs mailing list