Nikos Mavrogiannopoulos nmav@gnutls.org writes:
I was debugging an invalid memory access in gnutls and realized that the issue is in memxor3 of nettle (2.7.x branch). I have not yet a fix for that, but the attached patch modifies the memxor-test.c to reproduce the issue.
Hmm. If you have, e.g., a 14 byte block starting at address 0x1001, it usually harmless to do read that data as a two aligned reads at address 0x1000 and 0x1008, and then ignore the data outside of the area. Valgrind usually doesn't warn about that.
Now memxor on x86_64 is a bit special, since it tries to align the *writes*, but it does full-word *unaligned* reads. In this case, reading outside of the input area may cause serious problems, e.g, crossing a page boundary.
So this might be a fairly serious bug in the memxor assembly code.
void test_main(void) {
- uint8_t dst_buf[MAX_SIZE];
- uint8_t *c_buf;
- uint8_t *d_buf; const uint8_t *a = H("ecc8737f 38f2f9e8 86b9d84c 42a9c7ef" "27a50860 49c6be97 c5cc6c35 3981b367" "f8b4397b 951e3b2f 35749fe1 25884fa6"
@@ -144,4 +148,15 @@ test_main(void) for (align_b = 0; align_b < ALIGN_SIZE; align_b++) test_memxor3 (a, b, c, size[i], align_dst, align_a, align_b); }
- c_buf = malloc(111);
- d_buf = malloc(111);
- memset(c_buf, 1, 111);
- memset(d_buf, 3, 111);
- memxor3 (dst_buf+13, c_buf+96, d_buf, 15);
- ASSERT(dst_buf[14] == 2);
- free(c_buf);
- free(d_buf);
}
What result do you get with this test? Does it fail the assert, or does it exit successfuly when running without valgrind, but generate warnings/errors with valgrind?
The memxor-test.c in the repo tries to run memxor and memxor3 with all combinations of alignments and a selection of different sizes. And I get no warnings from
make check EMULATOR='$(VALGRIND)' TS_ALL=memxor-test
As far as I see, those tests *should* include the same size and alignments as in your test, so I wonder what's going on here.
Regards, /Niels