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

Bug#713836: regcomp(3) writes past end of regex_t



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.)


Reply to: