Commit | Line | Data |
---|---|---|
b2fd8f63 RW |
1 | Extracted from glibc upstream git repository. Changes to the ChangeLog have |
2 | been removed. This patch is needed to fix spurious segmentation faults on | |
3 | i686. | |
4 | ||
5 | From 3abeeec5f46ff036bd9df60bb096e20314ccd078 Mon Sep 17 00:00:00 2001 | |
6 | From: Adhemerval Zanella <adhemerval.zanella@linaro.org> | |
7 | Date: Tue, 14 Mar 2017 14:16:13 -0300 | |
8 | Subject: [PATCH] Fix i686 memchr overflow calculation (BZ#21182) | |
9 | ||
10 | This patch fixes the regression added by 23d2770 for final address | |
11 | overflow calculation. The subtraction of the considered size (16) | |
12 | at line 120 is at wrong place, for sizes less than 16 subsequent | |
13 | overflow check will not take in consideration an invalid size (since | |
14 | the subtraction will be negative). Also, the lea instruction also | |
15 | does not raise the carry flag (CF) that is used in subsequent jbe | |
16 | to check for overflow. | |
17 | ||
18 | The fix is to follow x86_64 logic from 3daef2c where the overflow | |
19 | is first check and a sub instruction is issued. In case of resulting | |
20 | negative size, CF will be set by the sub instruction and a NULL | |
21 | result will be returned. The patch also add similar tests reported | |
22 | in bug report. | |
23 | ||
24 | Checked on i686-linux-gnu and x86_64-linux-gnu. | |
25 | ||
26 | * string/test-memchr.c (do_test): Add BZ#21182 checks for address | |
27 | near end of a page. | |
28 | * sysdeps/i386/i686/multiarch/memchr-sse2.S (__memchr): Fix | |
29 | overflow calculation. | |
30 | --- | |
31 | string/test-memchr.c | 6 ++++++ | |
32 | sysdeps/i386/i686/multiarch/memchr-sse2.S | 2 +- | |
33 | 3 files changed, 15 insertions(+), 1 deletion(-) | |
34 | ||
35 | diff --git a/string/test-memchr.c b/string/test-memchr.c | |
36 | index 2403c9242b..669e092e7d 100644 | |
37 | --- a/string/test-memchr.c | |
38 | +++ b/string/test-memchr.c | |
39 | @@ -210,6 +210,12 @@ test_main (void) | |
40 | do_test (0, i, i + 1, i + 1, 0); | |
41 | } | |
42 | ||
43 | + /* BZ#21182 - wrong overflow calculation for i686 implementation | |
44 | + with address near end of the page. */ | |
45 | + for (i = 2; i < 16; ++i) | |
46 | + /* page_size is in fact getpagesize() * 2. */ | |
47 | + do_test (page_size / 2 - i, i, i, 1, 0x9B); | |
48 | + | |
49 | do_random_tests (); | |
50 | return ret; | |
51 | } | |
52 | diff --git a/sysdeps/i386/i686/multiarch/memchr-sse2.S b/sysdeps/i386/i686/multiarch/memchr-sse2.S | |
53 | index 910679cfc0..e41f324a77 100644 | |
54 | --- a/sysdeps/i386/i686/multiarch/memchr-sse2.S | |
55 | +++ b/sysdeps/i386/i686/multiarch/memchr-sse2.S | |
56 | @@ -117,7 +117,6 @@ L(crosscache): | |
57 | ||
58 | # ifndef USE_AS_RAWMEMCHR | |
59 | jnz L(match_case2_prolog1) | |
60 | - lea -16(%edx), %edx | |
61 | /* Calculate the last acceptable address and check for possible | |
62 | addition overflow by using satured math: | |
63 | edx = ecx + edx | |
64 | @@ -125,6 +124,7 @@ L(crosscache): | |
65 | add %ecx, %edx | |
66 | sbb %eax, %eax | |
67 | or %eax, %edx | |
68 | + sub $16, %edx | |
69 | jbe L(return_null) | |
70 | lea 16(%edi), %edi | |
71 | # else | |
72 | -- | |
73 | 2.12.2 | |
74 |