File CVE-2018-20230.patch of Package pspp
pspp-dump-sav: Issue error message for too-large extension records.
CVE-2018-20230.
--- a/utilities/pspp-dump-sav.c
+++ b/utilities/pspp-dump-sav.c
@@ -37,6 +37,7 @@
#include "gl/progname.h"
#include "gl/version-etc.h"
#include "gl/xalloc.h"
+#include "gl/xsize.h"
#define ID_MAX_LEN 64
@@ -99,7 +100,7 @@ static void read_simple_compressed_data (struct sfm_reader *, int max_cases);
static void read_zlib_compressed_data (struct sfm_reader *);
static struct text_record *open_text_record (
- struct sfm_reader *, size_t size);
+ struct sfm_reader *, size_t size, size_t count);
static void close_text_record (struct text_record *);
static bool read_variable_to_value_pair (struct text_record *,
char **key, char **value);
@@ -735,7 +736,7 @@ read_extra_product_info (struct sfm_reader *r,
const char *s;
printf ("%08llx: extra product info\n", (long long int) ftello (r->file));
- text = open_text_record (r, size * count);
+ text = open_text_record (r, size, count);
s = text_get_all (text);
print_string (s, strlen (s));
close_text_record (text);
@@ -749,7 +750,7 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count)
printf ("%08llx: multiple response sets\n",
(long long int) ftello (r->file));
- text = open_text_record (r, size * count);
+ text = open_text_record (r, size, count);
for (;;)
{
const char *name;
@@ -909,7 +910,7 @@ read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count)
printf ("%08llx: long variable names (short => long)\n",
(long long int) ftello (r->file));
- text = open_text_record (r, size * count);
+ text = open_text_record (r, size, count);
while (read_variable_to_value_pair (text, &var, &long_name))
printf ("\t%s => %s\n", var, long_name);
close_text_record (text);
@@ -926,7 +927,7 @@ read_long_string_map (struct sfm_reader *r, size_t size, size_t count)
printf ("%08llx: very long strings (variable => length)\n",
(long long int) ftello (r->file));
- text = open_text_record (r, size * count);
+ text = open_text_record (r, size, count);
while (read_variable_to_value_pair (text, &var, &length_s))
printf ("\t%s => %d\n", var, atoi (length_s));
close_text_record (text);
@@ -1004,7 +1005,7 @@ read_datafile_attributes (struct sfm_reader *r, size_t size, size_t count)
struct text_record *text;
printf ("%08llx: datafile attributes\n", (long long int) ftello (r->file));
- text = open_text_record (r, size * count);
+ text = open_text_record (r, size, count);
read_attributes (r, text, "datafile");
close_text_record (text);
}
@@ -1196,7 +1197,7 @@ read_variable_attributes (struct sfm_reader *r, size_t size, size_t count)
struct text_record *text;
printf ("%08llx: variable attributes\n", (long long int) ftello (r->file));
- text = open_text_record (r, size * count);
+ text = open_text_record (r, size, count);
for (;;)
{
const char *variable = text_tokenize (text, ':');
@@ -1389,18 +1390,23 @@ struct text_record
size_t pos; /* Current position in buffer. */
};
-/* Reads SIZE bytes into a text record for R,
+/* Reads SIZE * COUNT bytes into a text record for R,
and returns the new text record. */
static struct text_record *
-open_text_record (struct sfm_reader *r, size_t size)
+open_text_record (struct sfm_reader *r, size_t size, size_t count)
{
struct text_record *text = xmalloc (sizeof *text);
- char *buffer = xmalloc (size + 1);
- read_bytes (r, buffer, size);
+
+ if (size_overflow_p (xsum (1, xtimes (size, count))))
+ sys_error (r, "Extension record too large.");
+
+ size_t n_bytes = size * count;
+ char *buffer = xmalloc (n_bytes + 1);
+ read_bytes (r, buffer, n_bytes);
buffer[size] = '\0';
text->reader = r;
text->buffer = buffer;
- text->size = size;
+ text->size = n_bytes;
text->pos = 0;
return text;
}