Browse code

perl : Fix CVE-2018-6797, CVE-2018-6798, CVE-2018-6913

Change-Id: If479c2ff14e413b8af27276162459d29db0f9395
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/5179
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George

Xiaolin Li authored on 2018/05/24 06:26:37
Showing 5 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+From 510cc261d965ccfa427900ebb368fc4d337442d2 Mon Sep 17 00:00:00 2001
1
+From: Karl Williamson <khw@cpan.org>
2
+Date: Fri, 2 Feb 2018 15:14:27 -0700
3
+Subject: [PATCH] (perl #132227) restart a node if we change to uni rules
4
+ within the node and encounter a sharp S
5
+
6
+This could lead to a buffer overflow.
7
+
8
+(cherry picked from commit 190b97e86cd07d984ea2e9f0c844d33cd3399d21)
9
+---
10
+ regcomp.c | 12 ++++++++++++
11
+ 1 file changed, 12 insertions(+)
12
+
13
+diff --git a/regcomp.c b/regcomp.c
14
+index c6c7cb4925..d79bd191c9 100644
15
+--- a/regcomp.c
16
+@@ -13323,6 +13323,18 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
17
+                          * /u.  This includes the multi-char fold SHARP S to
18
+                          * 'ss' */
19
+                         if (UNLIKELY(ender == LATIN_SMALL_LETTER_SHARP_S)) {
20
++
21
++                            /* If the node started out having uni rules, we
22
++                             * wouldn't have gotten here.  So this means
23
++                             * something in the middle has changed it, but
24
++                             * didn't think it needed to reparse.  But this
25
++                             * sharp s now does indicate the need for
26
++                             * reparsing. */
27
++                            if (RExC_uni_semantics) {
28
++                                p = oldp;
29
++                                goto loopdone;
30
++                            }
31
++
32
+                             RExC_seen_unfolded_sharp_s = 1;
33
+                             maybe_exactfu = FALSE;
34
+                         }
35
+-- 
36
+2.15.1-424-g9478a660812
37
+
0 38
new file mode 100644
... ...
@@ -0,0 +1,125 @@
0
+From 0abf1e8d89aecd32dbdabda5da4d52a2d57a7cff Mon Sep 17 00:00:00 2001
1
+From: Karl Williamson <khw@cpan.org>
2
+Date: Tue, 6 Feb 2018 14:50:48 -0700
3
+Subject: [PATCH] [perl #132063]: Heap buffer overflow
4
+
5
+The proximal cause is several instances in regexec.c of the code
6
+assuming that the input was valid UTF-8, whereas the input was too short
7
+for what the start byte claimed it would be.
8
+
9
+I grepped through the core for any other similar uses, and did not find
10
+any.
11
+
12
+(cherry picked from commit fe7d8ba0a1bf567af8fa8fea128e2b9f4c553e84)
13
+---
14
+ regexec.c              | 29 ++++++++++++++++-------------
15
+ t/lib/warnings/regexec |  7 +++++++
16
+ 2 files changed, 23 insertions(+), 13 deletions(-)
17
+
18
+diff --git a/regexec.c b/regexec.c
19
+index 5735b997fd..ea432c39d3 100644
20
+--- a/regexec.c
21
+@@ -1466,7 +1466,9 @@ Perl_re_intuit_start(pTHX_
22
+                                            ? trie_utf8_fold                         \
23
+                                            :   trie_latin_utf8_fold)))
24
+ 
25
+-#define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uscan, len, uvc, charid, foldlen, foldbuf, uniflags) \
26
++/* 'uscan' is set to foldbuf, and incremented, so below the end of uscan is
27
++ * 'foldbuf+sizeof(foldbuf)' */
28
++#define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uc_end, uscan, len, uvc, charid, foldlen, foldbuf, uniflags) \
29
+ STMT_START {                                                                        \
30
+     STRLEN skiplen;                                                                 \
31
+     U8 flags = FOLD_FLAGS_FULL;                                                     \
32
+@@ -1474,7 +1476,7 @@ STMT_START {
33
+     case trie_flu8:                                                                 \
34
+         _CHECK_AND_WARN_PROBLEMATIC_LOCALE;                                         \
35
+         if (utf8_target && UTF8_IS_ABOVE_LATIN1(*uc)) {                             \
36
+-            _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(uc, uc + UTF8SKIP(uc));          \
37
++            _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(uc, uc_end - uc);                \
38
+         }                                                                           \
39
+         goto do_trie_utf8_fold;                                                     \
40
+     case trie_utf8_exactfa_fold:                                                    \
41
+@@ -1483,7 +1485,7 @@ STMT_START {
42
+     case trie_utf8_fold:                                                            \
43
+       do_trie_utf8_fold:                                                            \
44
+         if ( foldlen>0 ) {                                                          \
45
+-            uvc = utf8n_to_uvchr( (const U8*) uscan, UTF8_MAXLEN, &len, uniflags ); \
46
++            uvc = utf8n_to_uvchr( (const U8*) uscan, foldlen, &len, uniflags );     \
47
+             foldlen -= len;                                                         \
48
+             uscan += len;                                                           \
49
+             len=0;                                                                  \
50
+@@ -1500,7 +1502,7 @@ STMT_START {
51
+         /* FALLTHROUGH */                                                           \
52
+     case trie_latin_utf8_fold:                                                      \
53
+         if ( foldlen>0 ) {                                                          \
54
+-            uvc = utf8n_to_uvchr( (const U8*) uscan, UTF8_MAXLEN, &len, uniflags ); \
55
++            uvc = utf8n_to_uvchr( (const U8*) uscan, foldlen, &len, uniflags );     \
56
+             foldlen -= len;                                                         \
57
+             uscan += len;                                                           \
58
+             len=0;                                                                  \
59
+@@ -1519,7 +1521,7 @@ STMT_START {
60
+         }                                                                           \
61
+         /* FALLTHROUGH */                                                           \
62
+     case trie_utf8:                                                                 \
63
+-        uvc = utf8n_to_uvchr( (const U8*) uc, UTF8_MAXLEN, &len, uniflags );        \
64
++        uvc = utf8n_to_uvchr( (const U8*) uc, uc_end - uc, &len, uniflags );        \
65
+         break;                                                                      \
66
+     case trie_plain:                                                                \
67
+         uvc = (UV)*uc;                                                              \
68
+@@ -2599,10 +2601,10 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
69
+                     }
70
+                     points[pointpos++ % maxlen]= uc;
71
+                     if (foldlen || uc < (U8*)strend) {
72
+-                        REXEC_TRIE_READ_CHAR(trie_type, trie,
73
+-                                         widecharmap, uc,
74
+-                                         uscan, len, uvc, charid, foldlen,
75
+-                                         foldbuf, uniflags);
76
++                        REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc,
77
++                                             (U8 *) strend, uscan, len, uvc,
78
++                                             charid, foldlen, foldbuf,
79
++                                             uniflags);
80
+                         DEBUG_TRIE_EXECUTE_r({
81
+                             dump_exec_pos( (char *)uc, c, strend,
82
+                                         real_start, s, utf8_target, 0);
83
+@@ -5511,8 +5513,9 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
84
+ 		    if ( base && (foldlen || uc < (U8*)(reginfo->strend))) {
85
+ 			I32 offset;
86
+ 			REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc,
87
+-					     uscan, len, uvc, charid, foldlen,
88
+-					     foldbuf, uniflags);
89
++                                             (U8 *) reginfo->strend, uscan,
90
++                                             len, uvc, charid, foldlen,
91
++                                             foldbuf, uniflags);
92
+ 			charcount++;
93
+ 			if (foldlen>0)
94
+ 			    ST.longfold = TRUE;
95
+@@ -5642,8 +5645,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
96
+ 			while (foldlen) {
97
+ 			    if (!--chars)
98
+ 				break;
99
+-			    uvc = utf8n_to_uvchr(uscan, UTF8_MAXLEN, &len,
100
+-					    uniflags);
101
++			    uvc = utf8n_to_uvchr(uscan, foldlen, &len,
102
++                                                 uniflags);
103
+ 			    uscan += len;
104
+ 			    foldlen -= len;
105
+ 			}
106
+diff --git a/t/lib/warnings/regexec b/t/lib/warnings/regexec
107
+index 900dd6ee7f..6635142dea 100644
108
+--- a/t/lib/warnings/regexec
109
+@@ -260,3 +260,10 @@ setlocale(&POSIX::LC_CTYPE, $utf8_locale);
110
+ "k" =~ /(?[ \N{KELVIN SIGN} ])/i;
111
+ ":" =~ /(?[ \: ])/;
112
+ EXPECT
113
++########
114
++# NAME perl #132063, read beyond buffer end
115
++# OPTION fatal
116
++"\xff" =~ /(?il)\x{100}|\x{100}/;
117
++EXPECT
118
++Malformed UTF-8 character: \xff (too short; 1 byte available, need 13) in pattern match (m//) at - line 2.
119
++Malformed UTF-8 character (fatal) at - line 2.
120
+-- 
121
+2.15.1-424-g9478a660812
122
+
0 123
new file mode 100644
... ...
@@ -0,0 +1,32 @@
0
+From f65da1ca2eee74696d9c120e9d69af37b4fa1920 Mon Sep 17 00:00:00 2001
1
+From: Tony Cook <tony@develop-help.com>
2
+Date: Mon, 19 Feb 2018 15:11:42 +1100
3
+Subject: [PATCH] (perl #132063) we should no longer warn for this code
4
+
5
+The first patch for 132063 prevented the buffer read overflow when
6
+dumping the warning but didn't fix the underlying problem.
7
+
8
+The next change treats the supplied buffer correctly, preventing the
9
+non-UTF-8 SV from being treated as UTF-8, preventing the warning.
10
+
11
+(cherry picked from commit 1e8b61488f195e1396aa801c685340b156104f4f)
12
+---
13
+ t/lib/warnings/regexec | 3 ---
14
+ 1 file changed, 3 deletions(-)
15
+
16
+diff --git a/t/lib/warnings/regexec b/t/lib/warnings/regexec
17
+index 6635142dea..c370ddc3c7 100644
18
+--- a/t/lib/warnings/regexec
19
+@@ -262,8 +262,5 @@ setlocale(&POSIX::LC_CTYPE, $utf8_locale);
20
+ EXPECT
21
+ ########
22
+ # NAME perl #132063, read beyond buffer end
23
+-# OPTION fatal
24
+ "\xff" =~ /(?il)\x{100}|\x{100}/;
25
+ EXPECT
26
+-Malformed UTF-8 character: \xff (too short; 1 byte available, need 13) in pattern match (m//) at - line 2.
27
+-Malformed UTF-8 character (fatal) at - line 2.
28
+-- 
29
+2.15.1-424-g9478a660812
30
+
0 31
new file mode 100644
... ...
@@ -0,0 +1,143 @@
0
+From a9d5c6e11891b48be06d4e06eeed18642bc98527 Mon Sep 17 00:00:00 2001
1
+From: Tony Cook <tony@develop-help.com>
2
+Date: Tue, 8 Aug 2017 09:32:58 +1000
3
+Subject: [PATCH] (perl #131844) fix various space calculation issues in
4
+ pp_pack.c
5
+
6
+- for the originally reported case, if the start/cur pointer is in the
7
+  top 75% of the address space the add (cur) + glen addition would
8
+  overflow, resulting in the condition failing incorrectly.
9
+
10
+- the addition of the existing space used to the space needed could
11
+  overflow, resulting in too small an allocation and a buffer overflow.
12
+
13
+- the scaling for UTF8 could overflow.
14
+
15
+- the multiply to calculate the space needed for many items could
16
+  overflow.
17
+
18
+For the first case, do a space calculation without making new pointers.
19
+
20
+For the other cases, detect the overflow and croak if there's an
21
+overflow.
22
+
23
+Originally this used Size_t_MAX as the maximum size of a memory
24
+allocation, but for -DDEBUGGING builds realloc() throws a panic for
25
+allocations over half the address space in size, changing the error
26
+reported for the allocation.
27
+
28
+For non-DEBUGGING builds the Size_t_MAX limit has the small chance
29
+of finding a system that has 3GB of contiguous space available, and
30
+allocating that space, which could be a denial of servce in some cases.
31
+
32
+Unfortunately changing the limit to half the address space means that
33
+the exact case with the original issue can no longer occur, so the
34
+test is no longer testing against the address + length issue that
35
+caused the original problem, since the allocation is failing earlier.
36
+
37
+One option would be to change the test so the size request by pack is
38
+just under 2GB, but this has a higher (but still low) probability that
39
+the system has the address space available, and will actually try to
40
+allocate the memory, so let's not do that.
41
+
42
+(cherry picked from commit f5506feddde8546eabb69d71569d856c7e9c615b)
43
+---
44
+ pp_pack.c   | 25 +++++++++++++++++++++----
45
+ t/op/pack.t | 24 +++++++++++++++++++++++-
46
+ 2 files changed, 44 insertions(+), 5 deletions(-)
47
+
48
+diff --git a/pp_pack.c b/pp_pack.c
49
+index f6964c3f30..c0de5ab82b 100644
50
+--- a/pp_pack.c
51
+@@ -358,11 +358,28 @@ STMT_START {							\
52
+     }								\
53
+ } STMT_END
54
+ 
55
++#define SAFE_UTF8_EXPAND(var)	\
56
++STMT_START {				\
57
++    if ((var) > SSize_t_MAX / UTF8_EXPAND) \
58
++        Perl_croak(aTHX_ "%s", "Out of memory during pack()"); \
59
++    (var) = (var) * UTF8_EXPAND; \
60
++} STMT_END
61
++
62
++#define GROWING2(utf8, cat, start, cur, item_size, item_count)	\
63
++STMT_START {							\
64
++    if (SSize_t_MAX / (item_size) < (item_count))		\
65
++        Perl_croak(aTHX_ "%s", "Out of memory during pack()");	\
66
++    GROWING((utf8), (cat), (start), (cur), (item_size) * (item_count)); \
67
++} STMT_END
68
++
69
+ #define GROWING(utf8, cat, start, cur, in_len)	\
70
+ STMT_START {					\
71
+     STRLEN glen = (in_len);			\
72
+-    if (utf8) glen *= UTF8_EXPAND;		\
73
+-    if ((cur) + glen >= (start) + SvLEN(cat)) {	\
74
++    STRLEN catcur = (STRLEN)((cur) - (start));	\
75
++    if (utf8) SAFE_UTF8_EXPAND(glen);		\
76
++    if (SSize_t_MAX - glen < catcur)		\
77
++        Perl_croak(aTHX_ "%s", "Out of memory during pack()"); \
78
++    if (catcur + glen >= SvLEN(cat)) {	\
79
+ 	(start) = sv_exp_grow(cat, glen);	\
80
+ 	(cur) = (start) + SvCUR(cat);		\
81
+     }						\
82
+@@ -372,7 +389,7 @@ STMT_START {					\
83
+ STMT_START {					\
84
+     const STRLEN glen = (in_len);		\
85
+     STRLEN gl = glen;				\
86
+-    if (utf8) gl *= UTF8_EXPAND;		\
87
++    if (utf8) SAFE_UTF8_EXPAND(gl);		\
88
+     if ((cur) + gl >= (start) + SvLEN(cat)) {	\
89
+         *cur = '\0';				\
90
+         SvCUR_set((cat), (cur) - (start));	\
91
+@@ -2126,7 +2143,7 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
92
+ 	    if (props && !(props & PACK_SIZE_UNPREDICTABLE)) {
93
+ 		/* We can process this letter. */
94
+ 		STRLEN size = props & PACK_SIZE_MASK;
95
+-		GROWING(utf8, cat, start, cur, (STRLEN) len * size);
96
++		GROWING2(utf8, cat, start, cur, size, (STRLEN)len);
97
+ 	    }
98
+         }
99
+ 
100
+diff --git a/t/op/pack.t b/t/op/pack.t
101
+index a2da63689b..a480c3ad7f 100644
102
+--- a/t/op/pack.t
103
+@@ -12,7 +12,7 @@ my $no_endianness = $] > 5.009 ? '' :
104
+ my $no_signedness = $] > 5.009 ? '' :
105
+   "Signed/unsigned pack modifiers not available on this perl";
106
+ 
107
+-plan tests => 14712;
108
++plan tests => 14716;
109
+ 
110
+ use strict;
111
+ use warnings qw(FATAL all);
112
+@@ -2044,3 +2044,25 @@ ok(1, "argument underflow did not crash");
113
+     is(pack("H40", $up_nul), $twenty_nuls,
114
+        "check pack H zero fills (utf8 source)");
115
+ }
116
++
117
++SKIP:
118
++{
119
++  # [perl #131844] pointer addition overflow
120
++    $Config{ptrsize} == 4
121
++      or skip "[perl #131844] need 32-bit build for this test", 4;
122
++    # prevent ASAN just crashing on the allocation failure
123
++    local $ENV{ASAN_OPTIONS} = $ENV{ASAN_OPTIONS};
124
++    $ENV{ASAN_OPTIONS} .= ",allocator_may_return_null=1";
125
++    fresh_perl_like('pack "f999999999"', qr/Out of memory during pack/, { stderr => 1 },
126
++		    "pointer addition overflow");
127
++
128
++    # integer (STRLEN) overflow from addition of glen to current length
129
++    fresh_perl_like('pack "c10f1073741823"', qr/Out of memory during pack/, { stderr => 1 },
130
++		    "integer overflow calculating allocation (addition)");
131
++
132
++    fresh_perl_like('pack "W10f536870913", 256', qr/Out of memory during pack/, { stderr => 1 },
133
++		    "integer overflow calculating allocation (utf8)");
134
++
135
++    fresh_perl_like('pack "c10f1073741824"', qr/Out of memory during pack/, { stderr => 1 },
136
++		    "integer overflow calculating allocation (multiply)");
137
++}
138
+-- 
139
+2.15.1-424-g9478a660812
140
+
... ...
@@ -9,7 +9,7 @@
9 9
 Summary:        Practical Extraction and Report Language
10 10
 Name:           perl
11 11
 Version:        5.24.1
12
-Release:        4%{?dist}
12
+Release:        5%{?dist}
13 13
 License:        GPLv1+
14 14
 URL:            http://www.perl.org/
15 15
 Group:          Development/Languages
... ...
@@ -20,6 +20,10 @@ Source0:        http://www.cpan.org/src/5.0/%{name}-%{version}.tar.bz2
20 20
 Patch0:         CVE-2017-12883.patch
21 21
 #https://perl5.git.perl.org/perl.git/patch/96c83ed78aeea1a0496dd2b2d935869a822dc8a5
22 22
 Patch1:         CVE-2017-12837.patch
23
+Patch2:         perl-CVE-2018-6797.patch
24
+Patch3:         perl-CVE-2018-6798-1.patch
25
+Patch4:         perl-CVE-2018-6798-2.patch
26
+Patch5:         perl-CVE-2018-6913.patch
23 27
 Provides:       perl >= 0:5.003000
24 28
 Provides:       perl(getopts.pl)
25 29
 Provides:       /bin/perl
... ...
@@ -38,6 +42,10 @@ Report Language.
38 38
 sed -i 's/-fstack-protector/&-all/' Configure
39 39
 %patch0 -p1
40 40
 %patch1 -p1
41
+%patch2 -p1
42
+%patch3 -p1
43
+%patch4 -p1
44
+%patch5 -p1
41 45
 
42 46
 %build
43 47
 export BUILD_ZLIB=False
... ...
@@ -74,6 +82,8 @@ make test TEST_SKIP_VERSION_CHECK=1
74 74
 %{_libdir}/perl5/%{version}/*
75 75
 %{_mandir}/*/*
76 76
 %changelog
77
+*   Mon May 21 2018 Xiaolin <xiaolinl@vmware.com> 5.24.1-5
78
+-   Fix CVE-2018-6797, CVE-2018-6798, CVE-2018-6913
77 79
 *   Tue Oct 03 2017 Dheeraj Shetty <dheerajs@vmware.com> 5.24.1-4
78 80
 -   CVE-2017-12837 and CVE-2017-12883 patch from
79 81
 -   https://perl5.git.perl.org/perl.git/commitdiff/2be4edede4ae226e2eebd4eff28cedd2041f300f#patch1