[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