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: