Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8a3c0d4

Browse filesBrowse files
committed
restructure to use safe_memcpy to avoid memory leak
1 parent 71218d2 commit 8a3c0d4
Copy full SHA for 8a3c0d4

File tree

1 file changed

+54
-25
lines changed
Filter options

1 file changed

+54
-25
lines changed

‎Modules/mmapmodule.c

Copy file name to clipboardExpand all lines: Modules/mmapmodule.c
+54-25Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "pycore_bytesobject.h" // _PyBytes_Find()
2828
#include "pycore_fileutils.h" // _Py_stat_struct
2929

30+
#include <stdbool.h>
3031
#include <stddef.h> // offsetof()
3132
#ifndef MS_WINDOWS
3233
# include <unistd.h> // close()
@@ -255,6 +256,44 @@ do { \
255256
} while (0)
256257
#endif /* UNIX */
257258

259+
#if defined(MS_WIN32) && !defined(DONT_USE_SEH)
260+
static DWORD
261+
HandlePageException(EXCEPTION_POINTERS *ptrs, EXCEPTION_RECORD *record)
262+
{
263+
*record = *ptrs->ExceptionRecord;
264+
if (ptrs->ExceptionRecord->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) {
265+
return EXCEPTION_EXECUTE_HANDLER;
266+
}
267+
return EXCEPTION_CONTINUE_SEARCH;
268+
}
269+
#endif
270+
271+
bool
272+
safe_memcpy(void *restrict dest, const void *restrict src, size_t count) {
273+
#if defined(MS_WIN32) && !defined(DONT_USE_SEH)
274+
275+
// never fail for count 0
276+
if (count == 0) {
277+
return true;
278+
}
279+
280+
EXCEPTION_RECORD record;
281+
__try {
282+
memcpy(dest, src, count);
283+
return true;
284+
}
285+
__except (HandlePageException(GetExceptionInformation(), &record)) {
286+
NTSTATUS status = record.ExceptionInformation[2];
287+
ULONG code = LsaNtStatusToWinError(status);
288+
PyErr_SetFromWindowsErr(code);
289+
return false;
290+
}
291+
#else
292+
memcpy(dest, src, count);
293+
return true;
294+
#endif
295+
}
296+
258297
static PyObject *
259298
mmap_read_byte_method(mmap_object *self,
260299
PyObject *Py_UNUSED(ignored))
@@ -264,7 +303,14 @@ mmap_read_byte_method(mmap_object *self,
264303
PyErr_SetString(PyExc_ValueError, "read byte out of range");
265304
return NULL;
266305
}
267-
return PyLong_FromLong((unsigned char)self->data[self->pos++]);
306+
unsigned char dest;
307+
if (safe_memcpy(dest, self->data + self->pos, 1)) {
308+
self->pos++;
309+
return PyLong_FromLong(dest);
310+
}
311+
else {
312+
return NULL;
313+
}
268314
}
269315

270316
static PyObject *
@@ -291,17 +337,6 @@ mmap_read_line_method(mmap_object *self,
291337
return result;
292338
}
293339

294-
#if defined(MS_WIN32) && !defined(DONT_USE_SEH)
295-
static DWORD HandlePageException(EXCEPTION_POINTERS *ptrs, EXCEPTION_RECORD *record)
296-
{
297-
*record = *ptrs->ExceptionRecord;
298-
if (ptrs->ExceptionRecord->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) {
299-
return EXCEPTION_EXECUTE_HANDLER;
300-
}
301-
return EXCEPTION_CONTINUE_SEARCH;
302-
}
303-
#endif
304-
305340
static PyObject *
306341
mmap_read_method(mmap_object *self,
307342
PyObject *args)
@@ -319,22 +354,16 @@ mmap_read_method(mmap_object *self,
319354
if (num_bytes < 0 || num_bytes > remaining)
320355
num_bytes = remaining;
321356

322-
#if defined(MS_WIN32) && !defined(DONT_USE_SEH)
323-
EXCEPTION_RECORD record;
324-
__try {
325-
result = PyBytes_FromStringAndSize(&self->data[self->pos], num_bytes);
357+
result = PyBytes_FromStringAndSize(NULL, num_bytes);
358+
if (result == NULL) {
359+
return NULL;
360+
}
361+
if (safe_memcpy(((PyBytesObject *) result)->ob_sval, self->data + self->pos, num_bytes)) {
326362
self->pos += num_bytes;
327363
}
328-
__except (HandlePageException(GetExceptionInformation(), &record)) {
329-
NTSTATUS code = record.ExceptionInformation[2];
330-
PyErr_SetFromWindowsErr(code);
331-
result = NULL;
364+
else {
365+
Py_CLEAR(result);
332366
}
333-
#else
334-
result = PyBytes_FromStringAndSize(&self->data[self->pos], num_bytes);
335-
self->pos += num_bytes;
336-
#endif
337-
338367
return result;
339368
}
340369

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.