Browse code

python3 : Fix CVE-2018-1000117 and CVE-2017-18207

Change-Id: I8e6dbfecf1debccee462837e13397b364daab1fc
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/5042
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Anish Swaminathan <anishs@vmware.com>

Xiaolin Li authored on 2018/04/20 10:21:39
Showing 3 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,81 @@
0
+From 134cb01cda50f02725575808130b05d2d776693f Mon Sep 17 00:00:00 2001
1
+From: Serhiy Storchaka <storchaka@gmail.com>
2
+Date: Sun, 18 Mar 2018 09:55:53 +0200
3
+Subject: [PATCH] bpo-32056: Improve exceptions in aifc, wave and sunau.
4
+ (GH-5951)
5
+
6
+---
7
+ Lib/aifc.py                                        |  4 ++
8
+ Lib/sunau.py                                       |  2 +
9
+ Lib/test/test_aifc.py                              | 35 ++++++++++--
10
+ Lib/test/test_sunau.py                             | 37 +++++++++++++
11
+ Lib/test/test_wave.py                              | 62 ++++++++++++++++++++++
12
+ Lib/wave.py                                        | 14 ++++-
13
+ .../2018-03-01-17-49-56.bpo-32056.IlpfgE.rst       |  3 ++
14
+ 7 files changed, 150 insertions(+), 7 deletions(-)
15
+ create mode 100644 Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst
16
+
17
+diff --git a/Lib/aifc.py b/Lib/aifc.py
18
+index 3d2dc56de198..1916e7ef8e7e 100644
19
+--- a/Lib/aifc.py
20
+@@ -467,6 +467,10 @@ def _read_comm_chunk(self, chunk):
21
+         self._nframes = _read_long(chunk)
22
+         self._sampwidth = (_read_short(chunk) + 7) // 8
23
+         self._framerate = int(_read_float(chunk))
24
++        if self._sampwidth <= 0:
25
++            raise Error('bad sample width')
26
++        if self._nchannels <= 0:
27
++            raise Error('bad # of channels')
28
+         self._framesize = self._nchannels * self._sampwidth
29
+         if self._aifc:
30
+             #DEBUG: SGI's soundeditor produces a bad size :-(
31
+diff --git a/Lib/sunau.py b/Lib/sunau.py
32
+index dbad3db8392d..129502b0b417 100644
33
+--- a/Lib/sunau.py
34
+@@ -208,6 +208,8 @@ def initfp(self, file):
35
+             raise Error('unknown encoding')
36
+         self._framerate = int(_read_u32(file))
37
+         self._nchannels = int(_read_u32(file))
38
++        if not self._nchannels:
39
++            raise Error('bad # of channels')
40
+         self._framesize = self._framesize * self._nchannels
41
+         if self._hdr_size > 24:
42
+             self._info = file.read(self._hdr_size - 24)
43
+--- a/Lib/wave.py
44
+@@ -253,12 +253,22 @@ def readframes(self, nframes):
45
+     #
46
+ 
47
+     def _read_fmt_chunk(self, chunk):
48
+-        wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('<HHLLH', chunk.read(14))
49
++        try:
50
++            wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('<HHLLH', chunk.read(14))
51
++        except struct.error:
52
++            raise EOFError from None
53
+         if wFormatTag == WAVE_FORMAT_PCM:
54
+-            sampwidth = struct.unpack_from('<H', chunk.read(2))[0]
55
++            try:
56
++                sampwidth = struct.unpack_from('<H', chunk.read(2))[0]
57
++            except struct.error:
58
++                raise EOFError from None
59
+             self._sampwidth = (sampwidth + 7) // 8
60
++            if not self._sampwidth:
61
++                raise Error('bad sample width')
62
+         else:
63
+             raise Error('unknown format: %r' % (wFormatTag,))
64
++        if not self._nchannels:
65
++            raise Error('bad # of channels')
66
+         self._framesize = self._nchannels * self._sampwidth
67
+         self._comptype = 'NONE'
68
+         self._compname = 'not compressed'
69
+diff --git a/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst b/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst
70
+new file mode 100644
71
+index 000000000000..421aa3767794
72
+--- /dev/null
73
+@@ -0,0 +1,3 @@
74
++Improved exceptions raised for invalid number of channels and sample width
75
++when read an audio file in modules :mod:`aifc`, :mod:`wave` and
76
++:mod:`sunau`.
0 77
new file mode 100644
... ...
@@ -0,0 +1,160 @@
0
+From baa45079466eda1f5636a6d13f3a60c2c00fdcd3 Mon Sep 17 00:00:00 2001
1
+From: Steve Dower <steve.dower@microsoft.com>
2
+Date: Mon, 5 Mar 2018 14:26:28 -0800
3
+Subject: [PATCH] [3.6] bpo-33001: Prevent buffer overrun in os.symlink
4
+ (GH-5989) (GH-5990)
5
+
6
+---
7
+ Lib/test/test_os.py                                | 35 ++++++++++++
8
+ .../2018-03-05-10-09-51.bpo-33001.elj4Aa.rst       |  1 +
9
+ Modules/posixmodule.c                              | 66 +++++++++++++---------
10
+ 3 files changed, 74 insertions(+), 28 deletions(-)
11
+ create mode 100644 Misc/NEWS.d/next/Security/2018-03-05-10-09-51.bpo-33001.elj4Aa.rst
12
+
13
+diff --git a/Misc/NEWS.d/next/Security/2018-03-05-10-09-51.bpo-33001.elj4Aa.rst b/Misc/NEWS.d/next/Security/2018-03-05-10-09-51.bpo-33001.elj4Aa.rst
14
+new file mode 100644
15
+index 000000000000..2acbac9e1af6
16
+--- /dev/null
17
+@@ -0,0 +1 @@
18
++Minimal fix to prevent buffer overrun in os.symlink on Windows
19
+diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
20
+index 0837a4a4991e..39ba030b5191 100644
21
+--- a/Modules/posixmodule.c
22
+@@ -7241,7 +7241,7 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
23
+ #if defined(MS_WINDOWS)
24
+ 
25
+ /* Grab CreateSymbolicLinkW dynamically from kernel32 */
26
+-static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
27
++static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
28
+ static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
29
+ 
30
+ static int
31
+@@ -7259,18 +7259,24 @@ check_CreateSymbolicLink(void)
32
+     return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
33
+ }
34
+ 
35
+-/* Remove the last portion of the path */
36
+-static void
37
++/* Remove the last portion of the path - return 0 on success */
38
++static int
39
+ _dirnameW(WCHAR *path)
40
+ {
41
+     WCHAR *ptr;
42
+ 
43
++    size_t length = wcsnlen_s(path, MAX_PATH);
44
++    if (length == MAX_PATH) {
45
++        return -1;
46
++    }
47
+     /* walk the path from the end until a backslash is encountered */
48
+-    for(ptr = path + wcslen(path); ptr != path; ptr--) {
49
+-        if (*ptr == L'\\' || *ptr == L'/')
50
++    for(ptr = path + length; ptr != path; ptr--) {
51
++        if (*ptr == L'\\' || *ptr == L'/'){
52
+             break;
53
++   }
54
+     }
55
+     *ptr = 0;
56
++    return 0;
57
+ }
58
+ 
59
+ /* Remove the last portion of the path */
60
+@@ -7299,29 +7305,26 @@ _is_absW(const WCHAR *path)
61
+ static int
62
+ _is_absA(const char *path)
63
+ {
64
+-    return path[0] == '\\' || path[0] == '/' || path[1] == ':';
65
+-
66
++    return path[0] == L'\\' || path[0] == L'/' ||
67
++        (path[0] && path[1] == L':');
68
+ }
69
+ 
70
+-/* join root and rest with a backslash */
71
+-static void
72
++/* join root and rest with a backslash - return 0 on success */
73
++static int
74
+ _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
75
+ {
76
+-    size_t root_len;
77
+-
78
+     if (_is_absW(rest)) {
79
+-        wcscpy(dest_path, rest);
80
+-        return;
81
++        return wcscpy_s(dest_path, MAX_PATH, rest);
82
+     }
83
+ 
84
+-    root_len = wcslen(root);
85
+-
86
+-    wcscpy(dest_path, root);
87
+-    if(root_len) {
88
+-        dest_path[root_len] = L'\\';
89
+-        root_len++;
90
++    if (wcscpy_s(dest_path, MAX_PATH, root)) {
91
++        return -1;
92
+     }
93
+-    wcscpy(dest_path+root_len, rest);
94
++
95
++    if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
96
++        return -1;
97
++     }
98
++    return wcscat_s(dest_path, MAX_PATH, rest);
99
+ }
100
+ 
101
+ /* join root and rest with a backslash */
102
+@@ -7354,10 +7357,14 @@ _check_dirW(WCHAR *src, WCHAR *dest)
103
+     WCHAR src_resolved[MAX_PATH] = L"";
104
+ 
105
+     /* dest_parent = os.path.dirname(dest) */
106
+-    wcscpy(dest_parent, dest);
107
+-    _dirnameW(dest_parent);
108
++    if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
109
++        _dirnameW(dest_parent)) {
110
++        return 0;
111
++    }
112
+     /* src_resolved = os.path.join(dest_parent, src) */
113
+-    _joinW(src_resolved, dest_parent, src);
114
++    if (_joinW(src_resolved, dest_parent, src)) {
115
++        return 0;
116
++    }
117
+     return (
118
+         GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
119
+         && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
120
+@@ -7432,15 +7439,10 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
121
+         }
122
+ #endif
123
+ 
124
+-    if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
125
+-        PyErr_SetString(PyExc_ValueError,
126
+-            "symlink: src and dst must be the same type");
127
+-        return NULL;
128
+-    }
129
+ 
130
+ #ifdef MS_WINDOWS
131
+ 
132
+-    Py_BEGIN_ALLOW_THREADS
133
++    _Py_BEGIN_SUPPRESS_IPH
134
+     if (dst->wide) {
135
+         /* if src is a directory, ensure target_is_directory==1 */
136
+         target_is_directory |= _check_dirW(src->wide, dst->wide);
137
+@@ -7453,13 +7455,19 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
138
+         result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
139
+                                         target_is_directory);
140
+     }
141
+-    Py_END_ALLOW_THREADS
142
++    _Py_END_SUPPRESS_IPH
143
+ 
144
+     if (!result)
145
+         return path_error2(src, dst);
146
+ 
147
+ #else
148
+ 
149
++    if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
150
++        PyErr_SetString(PyExc_ValueError,
151
++            "symlink: src and dst must be the same type");
152
++        return NULL;
153
++    }
154
++
155
+     Py_BEGIN_ALLOW_THREADS
156
+ #if HAVE_SYMLINKAT
157
+     if (dir_fd != DEFAULT_DIR_FD)
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:        A high-level scripting language
2 2
 Name:           python3
3 3
 Version:        3.5.4
4
-Release:        1%{?dist}
4
+Release:        2%{?dist}
5 5
 License:        PSF
6 6
 URL:            http://www.python.org/
7 7
 Group:          System Environment/Programming
... ...
@@ -11,6 +11,8 @@ Source0:        https://www.python.org/ftp/python/%{version}/Python-%{version}.t
11 11
 %define         sha1 Python=4aacbd09ca6988255de84a98ab9e4630f584efba
12 12
 Patch0:         cgi3.patch
13 13
 Patch1:         sockWarning.patch
14
+Patch3:         python3-CVE-2018-1000117.patch
15
+Patch4:         python3-CVE-2017-18207.patch
14 16
 BuildRequires:  pkg-config >= 0.28
15 17
 BuildRequires:  bzip2-devel
16 18
 BuildRequires:  ncurses-devel >= 6.0-3
... ...
@@ -89,6 +91,8 @@ to build python programs.
89 89
 %setup -q -n Python-%{version}
90 90
 %patch0 -p1
91 91
 %patch1 -p1
92
+%patch3 -p1
93
+%patch4 -p1
92 94
 
93 95
 %build
94 96
 export OPT="${CFLAGS}"
... ...
@@ -193,6 +197,8 @@ rm -rf %{buildroot}/*
193 193
 %{_bindir}/idle*
194 194
 
195 195
 %changelog
196
+*   Wed Apr 18 2018 Xiaolin Li <xiaolinl@vmware.com> 3.5.4-2
197
+-   Fix CVE-2018-1000117 and CVE-2017-18207
196 198
 *   Mon Dec 04 2017 Kumar Kaushik <kaushikk@vmware.com> 3.5.4-1
197 199
 -   Upgrading to 3.5.4
198 200
 *   Tue Sep 26 2017 Anish Swaminathan <anishs@vmware.com> 3.5.3-7