From 78a0075be14a8613dc7e37a69631e44fb7e504fc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 21 May 2022 12:15:15 +0900 Subject: [PATCH] [gamecode] Plug a nasty buffer overflow This one is ancient: the code was essentially unmodified since release (just some formatting). Malformed vectors could sneak through due to map bugs (eg, "angles -90" instead of "angle -90" as in ad_tears) and the vector parsing code would continue past the end of the string and writing into unowned memory, potentially messing up the libc allocation records. Replacing with the obvious sscanf works nicely. Sometimes, Quake code is brilliant. Other times, it's a real face-palm. --- libs/gamecode/pr_parse.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/libs/gamecode/pr_parse.c b/libs/gamecode/pr_parse.c index c48617924..1f8f3cebd 100644 --- a/libs/gamecode/pr_parse.c +++ b/libs/gamecode/pr_parse.c @@ -215,10 +215,7 @@ ED_NewString (progs_t *pr, const char *string) VISIBLE qboolean ED_ParseEpair (progs_t *pr, pr_type_t *base, pr_def_t *key, const char *s) { - int i; - char *string; pr_def_t *def; - char *v, *w; pr_type_t *d; dfunction_t *func; @@ -234,17 +231,18 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, pr_def_t *key, const char *s) break; case ev_vector: - string = strdup (s); - v = string; - w = string; - for (i = 0; i < 3; i++) { - while (*v && *v != ' ') - v++; - *v = 0; - (&PR_PTR (float, d))[i] = atof (w); - w = v = v + 1; + vec3_t vec = {}; + char *str = alloca (strlen (s) + 1); + strcpy (str, s); + for (char *v = str; *v; v++) { + if (*v == ',') { + *v = ' '; + } } - free (string); + if (sscanf (s, "%f %f %f", VectorExpandAddr (vec)) != 3) { + Sys_Printf ("Malformed vector %s\n", s); + } + VectorCopy (vec, PR_PTR (vector, d)); break; case ev_entity: