Module Name: src Committed By: rillig Date: Sun Jan 9 12:43:52 UTC 2022
Modified Files: src/usr.bin/make: for.c nonints.h parse.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.162 -r1.163 src/usr.bin/make/for.c cvs rdiff -u -r1.235 -r1.236 src/usr.bin/make/nonints.h cvs rdiff -u -r1.646 -r1.647 src/usr.bin/make/parse.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/for.c diff -u src/usr.bin/make/for.c:1.162 src/usr.bin/make/for.c:1.163 --- src/usr.bin/make/for.c:1.162 Sun Jan 9 00:33:57 2022 +++ src/usr.bin/make/for.c Sun Jan 9 12:43:52 2022 @@ -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 *bo 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); Index: src/usr.bin/make/nonints.h diff -u src/usr.bin/make/nonints.h:1.235 src/usr.bin/make/nonints.h:1.236 --- src/usr.bin/make/nonints.h:1.235 Sat Jan 8 23:52:26 2022 +++ src/usr.bin/make/nonints.h Sun Jan 9 12:43:52 2022 @@ -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 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); Index: src/usr.bin/make/parse.c diff -u src/usr.bin/make/parse.c:1.646 src/usr.bin/make/parse.c:1.647 --- src/usr.bin/make/parse.c:1.646 Sun Jan 9 11:43:58 2022 +++ src/usr.bin/make/parse.c Sun Jan 9 12:43:52 2022 @@ -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) {