GNU bug report logs - #75900
doprnt.c buffer overflow

Previous Next

Package: emacs;

Reported by: Pip Cet <pipcet <at> protonmail.com>

Date: Mon, 27 Jan 2025 19:14:01 UTC

Severity: normal

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Pip Cet <pipcet <at> protonmail.com>
To: 75900 <at> debbugs.gnu.org, eggert <at> cs.ucla.edu
Subject: bug#75900: doprnt.c buffer overflow
Date: Mon, 27 Jan 2025 19:13:09 +0000
doprnt sometimes overflows its buffer, causing stack smashing and (if
we're lucky) a glibc abort when make_formatted_string calls it:

(gdb) p make_formatted_string
("01234567890123456789012345678901234567890123456789012345678901234567890123456789)0123456789)01234567890123456789012345678901234567890123456789")
[Thread 0x7fffda9ff6c0 (LWP 20144) exited]
*** stack smashing detected ***: terminated

The reason is that in doprnt, the variable bufsize indicates the number
of remaining bytes in the buf, and bufptr points to the current byte in
the buf, but sometimes a byte is written and bufsize is not updated:

      else if (! LEADING_CODE_P (fmtchar))
	{
	  if (EQ (quoting_style, Qstraight) && fmtchar == '`')
	    fmtchar = '\'';

	  *bufptr++ = fmtchar;
	  continue;
	}

and

	{
	  do
	    *bufptr++ = *src++;
	  while (--srclen != 0);
	}

do this.  In the former case, we must update bufsize as it will be used
again.  In the latter case, it's sufficient to set it to 0 as this is
the last successful printing operation in this call.

A related issue is that if a multibyte character produced by a %s format
option would overflow the buffer, doprnt returns the buffer size minus
one, as expected, but hasn't actually modified all of the buffer data:
the final bytes will refer to uninitialized stack data.

For example, on my system, where FRAME_MESSAGE_BUF_SIZE (f) is 832, this
call:

(gdb) p message ("%s%s", "xxxx", SDATA(Fmake_string (0x8aa, 0x10002, Qt)))

will print the string

"xxxx䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀䀀^@Z"

where the last characters are an ASCII NUL followed by a 'Z' (which I
put in the buffer after it was SAFE_ALLOCA'd).  The 'Z' should have been
overwritten, in which case message would still have printed two
unintended NUL characters.

I intend to fix the first two bugs, and fix message in a somewhat ugly
way for the other two.

Patches to follow once there is a bug number.

Pip





This bug report was last modified 167 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.