From 763373fa2a33e3a4e69f9cefca6690e3090712d4 Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Thu, 28 Feb 2019 13:41:32 -0500 Subject: [PATCH 1/4] Fix off-by-one bug in cPickle that caused it to use uninitialised memory on truncated pickles read from FILE*s. --- Modules/cPickle.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Modules/cPickle.c b/Modules/cPickle.c index 914ebb3eebeedf..217651b88f30f8 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -586,13 +586,15 @@ readline_file(Unpicklerobject *self, char **s) while (1) { Py_ssize_t bigger; char *newbuf; - for (; i < (self->buf_size - 1); i++) { - if (feof(self->fp) || - (self->buf[i] = getc(self->fp)) == '\n') { - self->buf[i + 1] = '\0'; - *s = self->buf; - return i + 1; - } + int newchar; + while (i < (self->buf_size - 1)) { + if (feof(self->fp)) + goto done; + if ((newchar = getc(self->fp)) == EOF) + goto done; + self->buf[i++] = newchar; + if (newchar == '\n') + goto done; } if (self->buf_size > (PY_SSIZE_T_MAX >> 1)) { PyErr_NoMemory(); @@ -607,6 +609,10 @@ readline_file(Unpicklerobject *self, char **s) self->buf = newbuf; self->buf_size = bigger; } +done: + self->buf[i] = '\0'; + *s = self->buf; + return i; } From 7d170a8b4bf42aa8ebce70676fe401b26f03f7cb Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Thu, 28 Feb 2019 13:54:40 -0500 Subject: [PATCH 2/4] Add news entry. --- .../Core and Builtins/2019-02-28-13-52-18-bpo-36149-GJdnh4.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18-bpo-36149-GJdnh4.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18-bpo-36149-GJdnh4.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18-bpo-36149-GJdnh4.rst new file mode 100644 index 00000000000000..672db6c1fc07cc --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18-bpo-36149-GJdnh4.rst @@ -0,0 +1,2 @@ +Fix use of uninitialized memory in cPickle when reading a truncated pickle +from a file object. From 15e04cd5e0f791b3fbfa7307b2144865debb0682 Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Thu, 28 Feb 2019 13:59:16 -0500 Subject: [PATCH 3/4] Fix NEWS.d filename. --- ...-36149-GJdnh4.rst => 2019-02-28-13-52-18.bpo-36149.GJdnh4.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/Core and Builtins/{2019-02-28-13-52-18-bpo-36149-GJdnh4.rst => 2019-02-28-13-52-18.bpo-36149.GJdnh4.rst} (100%) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18-bpo-36149-GJdnh4.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18.bpo-36149.GJdnh4.rst similarity index 100% rename from Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18-bpo-36149-GJdnh4.rst rename to Misc/NEWS.d/next/Core and Builtins/2019-02-28-13-52-18.bpo-36149.GJdnh4.rst From 2ddb589552b65c4d24843229215d62e9f4bf69da Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Fri, 1 Mar 2019 17:24:01 -0500 Subject: [PATCH 4/4] Address reviewer comments: move the function exit back to the inner loop instead of the end of the functoin. --- Modules/cPickle.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Modules/cPickle.c b/Modules/cPickle.c index 217651b88f30f8..f7c6feccafd03a 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -586,15 +586,16 @@ readline_file(Unpicklerobject *self, char **s) while (1) { Py_ssize_t bigger; char *newbuf; - int newchar; while (i < (self->buf_size - 1)) { - if (feof(self->fp)) - goto done; - if ((newchar = getc(self->fp)) == EOF) - goto done; - self->buf[i++] = newchar; - if (newchar == '\n') - goto done; + int newchar = getc(self->fp); + if (newchar != EOF) { + self->buf[i++] = newchar; + } + if (newchar == EOF || newchar == '\n') { + self->buf[i] = '\0'; + *s = self->buf; + return i; + } } if (self->buf_size > (PY_SSIZE_T_MAX >> 1)) { PyErr_NoMemory(); @@ -609,10 +610,6 @@ readline_file(Unpicklerobject *self, char **s) self->buf = newbuf; self->buf_size = bigger; } -done: - self->buf[i] = '\0'; - *s = self->buf; - return i; }