[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#713836: marked as done (regcomp(3) writes past end of regex_t; breaks kernel compile)



Your message dated 27 Jun 2013 02:31:23 -0400
with message-id <20130627063123.4937.qmail@science.horizon.com>
and subject line Bug#713836 was a system misconfiguration
has caused the Debian Bug report #713836,
regarding regcomp(3) writes past end of regex_t; breaks kernel compile
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
713836: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=713836
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: libc6
Version: 2.17-6
Architecture: i386
Severity: important

This problem cropped up while compiling the kernel; it breaks
arch/x86/tools/relocs.c.  I've tracked it down and reduced
it to a small test case.

With the given arguments, regcomp() corrupts the byte past the end of
its supplied regex_t buffer.  This obviously can cause any manner of
undesired program behavior.

Note that this is 32-bit i386, not 64-bit.

Here's a simple test program:

#include <regex.h>
#include <stdio.h>
#include <stdbool.h>

regex_t array[2];

static bool
is_zero(void const *p, size_t len)
{
	size_t i;
	unsigned char const *pp = p;
	bool rv = true;

	for (i = 0; i < len; i++) {
		if (pp[i]) {
			printf("J'accuse!  buf[%zu] = %#x\n",
				i, pp[i]);
			rv = false;
		}
	}
	return rv;
}

int
main(void)
{
	if (is_zero(array+1, sizeof array[1]))
		printf("array[1] confirmed all-zero\n");
	regcomp(array+0, "^pa_", REG_EXTENDED|REG_NOSUB);
	if (is_zero(array+1, sizeof array[1]))
		printf("array[1] confirmed all-zero\n");
	else
		printf("Bug!  array[1] has been overwritten!\n");
	return 0;
}

And here's what running it produces:
$ ./a.out
array[1] confirmed all-zero
J'accuse!  buf[0] = 0x18
Bug!  array[1] has been overwritten!
$ ldd ./a.out
        linux-gate.so.1 (0xf7784000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf75ea000)
        /lib/ld-linux.so.2 (0xf7785000)

(The fact that the libc6-i686 libraries, which I have installed, are
not being used is due libc6-i686 postinst not handling multiarch; I'll
report that separately.)

--- End Message ---
--- Begin Message ---
Turns out it was a stale header in /usr/local/include that was causing
the compiler to think the structure was 4 bytes smaller than the C
library did.  Buffer overruns were inevitable.

I think the reason it happened to show up now was that the only affected
source was a Linux kernel helper script that was very stable and so dodn't
get recompiled for a long time even though the C library had changed.

But then I was hunting a kernel bug and did a "make clean" as a
precaution, and kaboom.

--- End Message ---

Reply to: