Sat May 7 17:25:28 2022 UTC ()
make: fix off-by-one error in buffer for .WAIT nodes

Strangely, GCC didn't warn about this error.  For the buffer overflow to
actually happen, there would have to be a billion .WAIT nodes.


(rillig)
diff -r1.670 -r1.671 src/usr.bin/make/parse.c

cvs diff -r1.670 -r1.671 src/usr.bin/make/parse.c (expand / switch to unified diff)

--- src/usr.bin/make/parse.c 2022/04/18 16:09:05 1.670
+++ src/usr.bin/make/parse.c 2022/05/07 17:25:28 1.671
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: parse.c,v 1.670 2022/04/18 16:09:05 sjg Exp $ */ 1/* $NetBSD: parse.c,v 1.671 2022/05/07 17:25:28 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -96,27 +96,27 @@ @@ -96,27 +96,27 @@
96 96
97#include <sys/types.h> 97#include <sys/types.h>
98#include <sys/stat.h> 98#include <sys/stat.h>
99#include <errno.h> 99#include <errno.h>
100#include <stdarg.h> 100#include <stdarg.h>
101#include <stdint.h> 101#include <stdint.h>
102 102
103#include "make.h" 103#include "make.h"
104#include "dir.h" 104#include "dir.h"
105#include "job.h" 105#include "job.h"
106#include "pathnames.h" 106#include "pathnames.h"
107 107
108/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ 108/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
109MAKE_RCSID("$NetBSD: parse.c,v 1.670 2022/04/18 16:09:05 sjg Exp $"); 109MAKE_RCSID("$NetBSD: parse.c,v 1.671 2022/05/07 17:25:28 rillig Exp $");
110 110
111/* 111/*
112 * A file being read. 112 * A file being read.
113 */ 113 */
114typedef struct IncludedFile { 114typedef struct IncludedFile {
115 FStr name; /* absolute or relative to the cwd */ 115 FStr name; /* absolute or relative to the cwd */
116 unsigned lineno; /* 1-based */ 116 unsigned lineno; /* 1-based */
117 unsigned readLines; /* the number of physical lines that have 117 unsigned readLines; /* the number of physical lines that have
118 * been read from the file */ 118 * been read from the file */
119 unsigned forHeadLineno; /* 1-based */ 119 unsigned forHeadLineno; /* 1-based */
120 unsigned forBodyReadLines; /* the number of physical lines that have 120 unsigned forBodyReadLines; /* the number of physical lines that have
121 * been read from the file above the body of 121 * been read from the file above the body of
122 * the .for loop */ 122 * the .for loop */
@@ -689,31 +689,31 @@ ApplyDependencyOperator(GNodeType op) @@ -689,31 +689,31 @@ ApplyDependencyOperator(GNodeType op)
689 689
690/* 690/*
691 * We add a .WAIT node in the dependency list. After any dynamic dependencies 691 * We add a .WAIT node in the dependency list. After any dynamic dependencies
692 * (and filename globbing) have happened, it is given a dependency on each 692 * (and filename globbing) have happened, it is given a dependency on each
693 * previous child, back until the previous .WAIT node. The next child won't 693 * previous child, back until the previous .WAIT node. The next child won't
694 * be scheduled until the .WAIT node is built. 694 * be scheduled until the .WAIT node is built.
695 * 695 *
696 * We give each .WAIT node a unique name (mainly for diagnostics). 696 * We give each .WAIT node a unique name (mainly for diagnostics).
697 */ 697 */
698static void 698static void
699ApplyDependencySourceWait(bool isSpecial) 699ApplyDependencySourceWait(bool isSpecial)
700{ 700{
701 static unsigned wait_number = 0; 701 static unsigned wait_number = 0;
702 char wait_src[16]; 702 char name[6 + 10 + 1];
703 GNode *gn; 703 GNode *gn;
704 704
705 snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number); 705 snprintf(name, sizeof name, ".WAIT_%u", ++wait_number);
706 gn = Targ_NewInternalNode(wait_src); 706 gn = Targ_NewInternalNode(name);
707 if (doing_depend) 707 if (doing_depend)
708 RememberLocation(gn); 708 RememberLocation(gn);
709 gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN; 709 gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
710 LinkToTargets(gn, isSpecial); 710 LinkToTargets(gn, isSpecial);
711} 711}
712 712
713static bool 713static bool
714ApplyDependencySourceKeyword(const char *src, ParseSpecial special) 714ApplyDependencySourceKeyword(const char *src, ParseSpecial special)
715{ 715{
716 int keywd; 716 int keywd;
717 GNodeType targetAttr; 717 GNodeType targetAttr;
718 718
719 if (*src != '.' || !ch_isupper(src[1])) 719 if (*src != '.' || !ch_isupper(src[1]))