summaryrefslogtreecommitdiff
path: root/usr.bin/make
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2022-01-09 12:43:52 +0000
committerrillig <rillig@NetBSD.org>2022-01-09 12:43:52 +0000
commit377c8a2a59ba908e95cb1f0252d96558e470055e (patch)
tree132617c8c6f731b9ae99e4f6d8ce796a04d03515 /usr.bin/make
parentb793ac0e782f9e5559aeb69560bec7dc607ec9f0 (diff)
make: fix use-after-free in -dp mode (since yesterday)
In a .for loop that contains an unclosed .if directive, Cond_restore_depth generates an error message. If stack traces are enabled using the option '-dp', the details of the .for loop are added to the stack trace, but at that point, the ForLoop had already been freed. To reproduce: make-2022.01.09.00.33.57 -r -f unit-tests/directive-for.mk -dp
Diffstat (limited to 'usr.bin/make')
-rw-r--r--usr.bin/make/for.c22
-rw-r--r--usr.bin/make/nonints.h3
-rw-r--r--usr.bin/make/parse.c6
3 files changed, 18 insertions, 13 deletions
diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c
index 9402010f63a..b649e2eb07f 100644
--- a/usr.bin/make/for.c
+++ b/usr.bin/make/for.c
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.162 2022/01/09 00:33:57 rillig Exp $ */
+/* $NetBSD: for.c,v 1.163 2022/01/09 12:43:52 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
#include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: for.c,v 1.162 2022/01/09 00:33:57 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.163 2022/01/09 12:43:52 rillig Exp $");
typedef struct ForLoop {
@@ -85,7 +85,7 @@ ForLoop_New(void)
return f;
}
-static void
+void
ForLoop_Free(ForLoop *f)
{
while (f->vars.len > 0)
@@ -101,11 +101,16 @@ ForLoop_Free(ForLoop *f)
char *
ForLoop_Details(ForLoop *f)
{
- size_t i, n = f->vars.len;
- const char **vars = f->vars.items;
- const Substring *items = f->items.words + f->nextItem - n;
+ size_t i, n;
+ const char **vars;
+ const Substring *items;
Buffer buf;
+ n = f->vars.len;
+ vars = f->vars.items;
+ assert(f->nextItem >= n);
+ items = f->items.words + f->nextItem - n;
+
Buf_Init(&buf);
for (i = 0; i < n; i++) {
if (i > 0)
@@ -474,11 +479,8 @@ ForLoop_SubstBody(ForLoop *f, Buffer *body)
bool
For_NextIteration(ForLoop *f, Buffer *body)
{
- if (f->nextItem == f->items.len) {
- /* No more iterations */
- ForLoop_Free(f);
+ if (f->nextItem == f->items.len)
return false;
- }
ForLoop_SubstBody(f, body);
DEBUG1(FOR, "For: loop body:\n%s", body->data);
diff --git a/usr.bin/make/nonints.h b/usr.bin/make/nonints.h
index 387e9715879..ce66be56009 100644
--- a/usr.bin/make/nonints.h
+++ b/usr.bin/make/nonints.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nonints.h,v 1.235 2022/01/08 23:52:26 rillig Exp $ */
+/* $NetBSD: nonints.h,v 1.236 2022/01/09 12:43:52 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -122,6 +122,7 @@ bool For_Accum(const char *, int *) MAKE_ATTR_USE;
void For_Run(int, int);
bool For_NextIteration(struct ForLoop *, Buffer *);
char *ForLoop_Details(struct ForLoop *);
+void ForLoop_Free(struct ForLoop *);
/* job.c */
void JobReapChild(pid_t, int, bool);
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c
index e10869dbc5a..f7f9c814c7a 100644
--- a/usr.bin/make/parse.c
+++ b/usr.bin/make/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.646 2022/01/09 11:43:58 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.647 2022/01/09 12:43:52 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -106,7 +106,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.646 2022/01/09 11:43:58 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.647 2022/01/09 12:43:52 rillig Exp $");
/*
* A file being read.
@@ -2253,6 +2253,8 @@ ParseEOF(void)
FStr_Done(&curFile->name);
Buf_Done(&curFile->buf);
+ if (curFile->forLoop != NULL)
+ ForLoop_Free(curFile->forLoop);
Vector_Pop(&includes);
if (includes.len == 0) {