summaryrefslogtreecommitdiff
path: root/devel/cscope
diff options
context:
space:
mode:
authorsalo <salo>2006-08-24 22:02:02 +0000
committersalo <salo>2006-08-24 22:02:02 +0000
commit2ff5e91533e17075470dd9de6cdf74cd24ef48d5 (patch)
tree0a467d9e658aa9b5f6de8beb294957e4406daba6 /devel/cscope
parent7acd7c964eb21224c67ff8f99fcd001ba1568229 (diff)
downloadpkgsrc-2ff5e91533e17075470dd9de6cdf74cd24ef48d5.tar.gz
Security fix for SA21601:
"Will Drewry has reported some vulnerabilities in Cscope, which potentially can be exploited by malicious people to compromise a vulnerable system. 1) Various boundary errors within the parsing of file lists or the expansion of environment variables can be exploited to cause stack-based buffer overflows when parsing specially crafted "cscope.lists" files or directories. 2) A boundary error within the parsing of command line arguments can be exploited to cause a stack-based buffer overflow when supplying an overly long "reffile" argument. Successful exploitation may allow execution of arbitrary code." Patches adapted from cscope CVS. Bump PKGREVISION.
Diffstat (limited to 'devel/cscope')
-rw-r--r--devel/cscope/Makefile4
-rw-r--r--devel/cscope/distinfo17
-rw-r--r--devel/cscope/patches/patch-aa30
-rw-r--r--devel/cscope/patches/patch-ae42
-rw-r--r--devel/cscope/patches/patch-af56
-rw-r--r--devel/cscope/patches/patch-ag17
-rw-r--r--devel/cscope/patches/patch-ah27
-rw-r--r--devel/cscope/patches/patch-ai21
-rw-r--r--devel/cscope/patches/patch-aj28
-rw-r--r--devel/cscope/patches/patch-ap24
10 files changed, 219 insertions, 47 deletions
diff --git a/devel/cscope/Makefile b/devel/cscope/Makefile
index f32918d8e3d..e1e5e8b73f9 100644
--- a/devel/cscope/Makefile
+++ b/devel/cscope/Makefile
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.44 2006/05/29 13:48:53 tron Exp $
+# $NetBSD: Makefile,v 1.45 2006/08/24 22:02:02 salo Exp $
DISTNAME= cscope-15.5
-PKGREVISION= 1
+PKGREVISION= 2
CATEGORIES= devel
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=cscope/}
diff --git a/devel/cscope/distinfo b/devel/cscope/distinfo
index 9cb693160eb..d0397dfc9ee 100644
--- a/devel/cscope/distinfo
+++ b/devel/cscope/distinfo
@@ -1,20 +1,21 @@
-$NetBSD: distinfo,v 1.14 2006/05/29 13:51:20 tron Exp $
+$NetBSD: distinfo,v 1.15 2006/08/24 22:02:02 salo Exp $
SHA1 (cscope-15.5.tar.gz) = 2e8e66735254328399dc50757b270bcc3e9002d3
RMD160 (cscope-15.5.tar.gz) = 30623f07043abc90d76b384c407abe5813a8a716
Size (cscope-15.5.tar.gz) = 243793 bytes
-SHA1 (patch-aa) = 8350f5bd050fac10c5b5b5dcd7c04e7f3a883324
+SHA1 (patch-aa) = 8c477f12c67ed91b7700cf70209c3a2b64309b15
SHA1 (patch-ab) = 646512ad53b3f3e7dab607df4c6c3d775587a03c
SHA1 (patch-ac) = 40a69af0eb5419de827b490c960803a736040f2c
SHA1 (patch-ad) = 7e0f25b67f3476ac90b7541595649d6a6bf65aa9
-SHA1 (patch-ae) = 0aeef81b7a18123b9814d2d93d0e08c5001f10da
-SHA1 (patch-af) = ecb2c1773b54b68e008d6afd3efc873e618ce116
-SHA1 (patch-ag) = 43f05ff194b7af96416dbd709bdc5d93080c2a0a
-SHA1 (patch-ah) = bdf4beaa30cac9032714655150f757fc5ec86210
-SHA1 (patch-ai) = fec9e178942585599163532741f76f0394fea26d
-SHA1 (patch-aj) = 8ca77d3b72bd7882db285b9b7422ae687a751bee
+SHA1 (patch-ae) = bf3ec3c4c8a8d245b7fe4745dd114fa4d253b0b9
+SHA1 (patch-af) = 816774a459cd68c6d24dc5bb436146d3e537fb5f
+SHA1 (patch-ag) = 1a94f675d2878268af7de488a5f81ae08a855715
+SHA1 (patch-ah) = 4e723e863b85f812e1dc993758b22f50554a4222
+SHA1 (patch-ai) = 19cea85408c7ab98b9b3021cd6af07794dae62f9
+SHA1 (patch-aj) = aab596f780ef213c9198f6d03886140ee7d0bcf8
SHA1 (patch-ak) = eb61acfd3f265656d5495e7b1a1b3cf6071213c6
SHA1 (patch-al) = 511ea0dd04b4062fac97bfd01c1a71de44e1c452
SHA1 (patch-am) = 2c08e2ccf22b3a3852c52d5177c7a08d206c1cdf
SHA1 (patch-an) = cef8d1d31a417125c516df403dce228ac92a307c
SHA1 (patch-ao) = 05ae43171f04320dc1a213510b0906d3387cf35f
+SHA1 (patch-ap) = 7e1af46170ac5304a784d2719b14aae01bd4a659
diff --git a/devel/cscope/patches/patch-aa b/devel/cscope/patches/patch-aa
index ceafdd5fb4d..7e1c5717e75 100644
--- a/devel/cscope/patches/patch-aa
+++ b/devel/cscope/patches/patch-aa
@@ -1,8 +1,30 @@
-$NetBSD: patch-aa,v 1.10 2006/03/23 16:09:32 yyamano Exp $
+$NetBSD: patch-aa,v 1.11 2006/08/24 22:02:02 salo Exp $
---- src/constants.h.orig 2003-09-05 00:54:02.000000000 +0900
-+++ src/constants.h
-@@ -95,7 +95,7 @@
+--- src/constants.h.orig 2003-09-04 17:54:02.000000000 +0200
++++ src/constants.h 2006-08-24 23:49:25.000000000 +0200
+@@ -68,6 +68,7 @@
+ #define NUMLEN 5 /* line number length */
+ #define PATHLEN 250 /* file pathname length */
+ #define PATLEN 250 /* symbol pattern length */
++#define TEMPSTRING_LEN 8191 /* max strlen() of the global temp string */
+ #define REFFILE "cscope.out" /* cross-reference output file */
+ #define NAMEFILE "cscope.files" /* default list-of-files file */
+ #define INVNAME "cscope.in.out" /* inverted index to the database */
+@@ -77,6 +78,13 @@
+
+ #define STMTMAX 10000 /* maximum source statement length */
+
++#define STR2(x) #x
++#define STRINGIZE(x) STR2(x)
++#define PATLEN_STR STRINGIZE(PATLEN)
++#define PATHLEN_STR STRINGIZE(PATHLEN)
++#define NUMLEN_STR STRINGIZE(NUMLEN)
++#define TEMPSTRING_LEN_STR STRINGIZE(TEMPSTRING_LEN)
++
+ /* screen lines */
+ #define FLDLINE (LINES - FIELDS - 1) /* first input field line */
+ #define MSGLINE 0 /* message line */
+@@ -95,7 +103,7 @@
#define INCLUDES 8
#define FIELDS 9
diff --git a/devel/cscope/patches/patch-ae b/devel/cscope/patches/patch-ae
index 69efc6beada..69dd6758990 100644
--- a/devel/cscope/patches/patch-ae
+++ b/devel/cscope/patches/patch-ae
@@ -1,7 +1,16 @@
-$NetBSD: patch-ae,v 1.8 2006/05/29 13:51:20 tron Exp $
+$NetBSD: patch-ae,v 1.9 2006/08/24 22:02:02 salo Exp $
---- src/build.c.orig 2003-03-05 10:43:59.000000000 +0000
-+++ src/build.c 2006-05-29 14:34:26.000000000 +0100
+--- src/build.c.orig 2003-03-05 11:43:59.000000000 +0100
++++ src/build.c 2006-08-24 23:26:31.000000000 +0200
+@@ -115,7 +115,7 @@
+ }
+ /* see if the name list is the same */
+ for (i = 0; i < count; ++i) {
+- if (fscanf(oldrefs, "%s", oldname) != 1 ||
++ if (! fgets(oldname, sizeof(oldname), oldrefs)||
+ strnotequal(oldname, names[i])) {
+ return(NO);
+ }
@@ -215,7 +215,7 @@
(void) strcpy(newdir, "$HOME");
}
@@ -11,6 +20,33 @@ $NetBSD: patch-ae,v 1.8 2006/05/29 13:51:20 tron Exp $
}
/* sort the source file names (needed for rebuilding) */
qsort(srcfiles, (unsigned) nsrcfiles, sizeof(char *), compare);
+@@ -223,7 +223,7 @@
+ /* if there is an old cross-reference and its current directory matches */
+ /* or this is an unconditional build */
+ if ((oldrefs = vpfopen(reffile, "rb")) != NULL && unconditional == NO &&
+- fscanf(oldrefs, "cscope %d %s", &fileversion, olddir) == 2 &&
++ fscanf(oldrefs, "cscope %d %" PATHLEN_STR "s", &fileversion, olddir) == 2 &&
+ (strcmp(olddir, currentdir) == 0 || /* remain compatible */
+ strcmp(olddir, newdir) == 0)) {
+ /* get the cross-reference file's modification time */
+@@ -292,7 +292,7 @@
+ /* see if the list of source files is the same and
+ none have been changed up to the included files */
+ for (i = 0; i < nsrcfiles; ++i) {
+- if (fscanf(oldrefs, "%s", oldname) != 1 ||
++ if (! fgets(oldname, sizeof(oldname), oldrefs) ||
+ strnotequal(oldname, srcfiles[i]) ||
+ lstat(srcfiles[i], &statstruct) != 0 ||
+ statstruct.st_mtime > reftime) {
+@@ -301,7 +301,7 @@
+ }
+ /* the old cross-reference is up-to-date */
+ /* so get the list of included files */
+- while (i++ < oldnum && fscanf(oldrefs, "%s", oldname) == 1) {
++ while (i++ < oldnum && fgets(oldname, sizeof(oldname), oldrefs)) {
+ addsrcfile(oldname);
+ }
+ (void) fclose(oldrefs);
@@ -443,7 +443,7 @@
}
(void) fstat(fileno(postings), &statstruct);
diff --git a/devel/cscope/patches/patch-af b/devel/cscope/patches/patch-af
index 6f356d231db..637bf525936 100644
--- a/devel/cscope/patches/patch-af
+++ b/devel/cscope/patches/patch-af
@@ -1,8 +1,29 @@
-$NetBSD: patch-af,v 1.7 2006/05/29 13:51:20 tron Exp $
+$NetBSD: patch-af,v 1.8 2006/08/24 22:02:02 salo Exp $
---- src/main.c.orig 2003-08-14 15:36:18.000000000 +0100
-+++ src/main.c 2006-05-29 14:34:26.000000000 +0100
-@@ -330,9 +330,31 @@
+--- src/main.c.orig 2003-08-14 16:36:18.000000000 +0200
++++ src/main.c 2006-08-24 23:58:29.000000000 +0200
+@@ -103,7 +103,7 @@ char temp1[PATHLEN + 1]; /* temporary fi
+ char temp2[PATHLEN + 1]; /* temporary file name */
+ long totalterms; /* total inverted index terms */
+ BOOL trun_syms; /* truncate symbols to 8 characters */
+-char tempstring[8192]; /* use this as a buffer, instead of 'yytext',
++char tempstring[TEMPSTRING_LEN + 1]; /* use this as a buffer, instead of 'yytext',
+ * which had better be left alone */
+ char *tmpdir; /* temporary directory */
+
+@@ -247,6 +247,11 @@ main(int argc, char **argv)
+ switch (c) {
+ case 'f': /* alternate cross-reference file */
+ reffile = s;
++ if (strlen(reffile) > sizeof(path) - 1) {
++ posterr("\
++cscope: reffile too long, cannot be > %d characters\n", sizeof(path) - 1);
++ /* NOTREACHED */
++ }
+ (void) strcpy(path, s);
+ #ifdef SHORT_NAMES_ONLY
+ /* System V has a 14 character limit */
+@@ -330,9 +335,31 @@ lastarg:
}
/* create the temporary file names */
@@ -37,7 +58,7 @@ $NetBSD: patch-af,v 1.7 2006/05/29 13:51:20 tron Exp $
/* if running in the foreground */
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
-@@ -352,12 +374,12 @@
+@@ -352,12 +379,12 @@ lastarg:
* used instead of failing to open a non-existant database in
* the home directory
*/
@@ -53,7 +74,30 @@ $NetBSD: patch-af,v 1.7 2006/05/29 13:51:20 tron Exp $
invpost = stralloc(path);
}
}
-@@ -692,7 +714,7 @@
+@@ -467,11 +494,11 @@ lastarg:
+ || (names = vpfopen(NAMEFILE, "r")) != NULL) {
+
+ /* read any -p option from it */
+- while (fscanf(names, "%s", path) == 1 && *path == '-') {
++ while (fgets(path, sizeof(path), names) != NULL && *path == '-') {
+ i = path[1];
+ s = path + 2; /* for "-Ipath" */
+ if (*s == '\0') { /* if "-I path" */
+- (void) fscanf(names, "%s", path);
++ (void) fgets(path, sizeof(path), names);
+ s = path;
+ }
+ switch (i) {
+@@ -488,7 +515,7 @@ lastarg:
+ }
+ else {
+ for (i = 0; i < nsrcfiles; ++i) {
+- if (fscanf(oldrefs, "%s", path) != 1) {
++ if (!fgets(path, sizeof(path), oldrefs) ) {
+ posterr("cscope: cannot read source file name from file %s\n", reffile);
+ myexit(1);
+ }
+@@ -692,7 +719,7 @@ cannotwrite(char *file)
#else
char *msg = mymalloc(50+strlen(file));
diff --git a/devel/cscope/patches/patch-ag b/devel/cscope/patches/patch-ag
index 5ca83c006c8..a2ff03d9cb8 100644
--- a/devel/cscope/patches/patch-ag
+++ b/devel/cscope/patches/patch-ag
@@ -1,8 +1,17 @@
-$NetBSD: patch-ag,v 1.4 2006/05/29 13:51:20 tron Exp $
+$NetBSD: patch-ag,v 1.5 2006/08/24 22:02:02 salo Exp $
---- src/command.c.orig 2002-07-29 13:37:49.000000000 +0100
-+++ src/command.c 2006-05-29 14:34:26.000000000 +0100
-@@ -718,7 +718,7 @@
+--- src/command.c.orig 2002-07-29 14:37:49.000000000 +0200
++++ src/command.c 2006-08-24 23:31:53.000000000 +0200
+@@ -707,7 +707,7 @@ changestring(void)
+ (void) fprintf(script, "ed - <<\\!\n");
+ *oldfile = '\0';
+ seekline(1);
+- for (i = 0; fscanf(refsfound, "%s%*s%s%*[^\n]", newfile, linenum) == 2;
++ for (i = 0; fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", newfile, linenum) == 2;
+ ++i) {
+ /* see if the line is to be changed */
+ if (change[i] == YES) {
+@@ -718,7 +718,7 @@ changestring(void)
/* make sure it can be changed */
if (access(newfile, WRITE) != 0) {
diff --git a/devel/cscope/patches/patch-ah b/devel/cscope/patches/patch-ah
index b54a3804208..c0d1c16f537 100644
--- a/devel/cscope/patches/patch-ah
+++ b/devel/cscope/patches/patch-ah
@@ -1,8 +1,8 @@
-$NetBSD: patch-ah,v 1.4 2006/05/29 13:51:20 tron Exp $
+$NetBSD: patch-ah,v 1.5 2006/08/24 22:02:02 salo Exp $
---- src/dir.c.orig 2003-06-02 11:43:00.000000000 +0100
-+++ src/dir.c 2006-05-29 14:34:26.000000000 +0100
-@@ -138,7 +138,7 @@
+--- src/dir.c.orig 2003-06-02 12:43:00.000000000 +0200
++++ src/dir.c 2006-08-24 23:34:52.000000000 +0200
+@@ -138,7 +138,7 @@ sourcedir(char *dirlist)
/* compute its path from higher view path source dirs */
for (i = 1; i < nvpsrcdirs; ++i) {
@@ -11,7 +11,7 @@ $NetBSD: patch-ah,v 1.4 2006/05/29 13:51:20 tron Exp $
PATHLEN - 2 - dir_len,
srcdirs[i], dir);
addsrcdir(path);
-@@ -206,7 +206,7 @@
+@@ -206,7 +206,7 @@ includedir(char *dirlist)
/* compute its path from higher view path source dirs */
for (i = 1; i < nvpsrcdirs; ++i) {
@@ -20,7 +20,16 @@ $NetBSD: patch-ah,v 1.4 2006/05/29 13:51:20 tron Exp $
PATHLEN - 2 - dir_len,
srcdirs[i], dir);
addincdir(dir, path);
-@@ -474,8 +474,6 @@
+@@ -319,7 +319,7 @@ makefilelist(void)
+
+ /* Parse whitespace-terminated strings in line: */
+ point_in_line = line;
+- while (sscanf(point_in_line, "%s", path) == 1) {
++ while (sscanf(point_in_line, "%" PATHLEN_STR "s", path) == 1) {
+ /* Have to store this length --- inviewpath() will
+ * modify path, later! */
+ length_of_name = strlen(path);
+@@ -474,8 +474,6 @@ scan_dir(const char *adir, BOOL recurse_
DIR *dirfile;
int adir_len = strlen(adir);
@@ -29,7 +38,7 @@ $NetBSD: patch-ah,v 1.4 2006/05/29 13:51:20 tron Exp $
if ((dirfile = opendir(adir)) != NULL) {
struct dirent *entry;
char path[PATHLEN + 1];
-@@ -486,7 +484,7 @@
+@@ -486,7 +484,7 @@ scan_dir(const char *adir, BOOL recurse_
&& (strcmp("..",entry->d_name) != 0)) {
struct stat buf;
@@ -38,7 +47,7 @@ $NetBSD: patch-ah,v 1.4 2006/05/29 13:51:20 tron Exp $
PATHLEN - 2 - adir_len,
entry->d_name);
-@@ -603,14 +601,14 @@
+@@ -603,14 +601,14 @@ incfile(char *file, char *type)
for (i = 0; i < nincdirs; ++i) {
/* don't include the file from two directories */
@@ -55,7 +64,7 @@ $NetBSD: patch-ah,v 1.4 2006/05/29 13:51:20 tron Exp $
PATHLEN - 2 - file_len, incdirs[i],
file);
if (access(compath(path), READ) == 0) {
-@@ -654,7 +652,7 @@
+@@ -654,7 +652,7 @@ inviewpath(char *file)
/* compute its path from higher view path source dirs */
for (i = 1; i < nvpsrcdirs; ++i) {
diff --git a/devel/cscope/patches/patch-ai b/devel/cscope/patches/patch-ai
index 1f915a43089..9f19394ffa7 100644
--- a/devel/cscope/patches/patch-ai
+++ b/devel/cscope/patches/patch-ai
@@ -1,8 +1,17 @@
-$NetBSD: patch-ai,v 1.4 2006/05/29 13:51:20 tron Exp $
+$NetBSD: patch-ai,v 1.5 2006/08/24 22:02:02 salo Exp $
---- src/display.c.orig 2003-09-04 16:54:02.000000000 +0100
-+++ src/display.c 2006-05-29 14:34:26.000000000 +0100
-@@ -473,24 +473,24 @@
+--- src/display.c.orig 2003-09-04 17:54:02.000000000 +0200
++++ src/display.c 2006-08-24 23:37:28.000000000 +0200
+@@ -216,7 +216,7 @@ display(void)
+ disprefs < mdisprefs && screenline <= lastdispline;
+ ++disprefs, ++screenline) {
+ /* read the reference line */
+- if (fscanf(refsfound, "%s%s%s %[^\n]", file, function,
++ if (fscanf(refsfound, "%" PATHLEN_STR "s%" PATHLEN_STR "s%" NUMLEN_STR "s %" TEMPSTRING_LEN_STR "[^\n]", file, function,
+ linenum, tempstring) < 4) {
+ break;
+ }
+@@ -473,24 +473,24 @@ search(void)
/* see if it is empty */
if ((c = getc(refsfound)) == EOF) {
if (findresult != NULL) {
@@ -32,7 +41,7 @@ $NetBSD: patch-ai,v 1.4 2006/05/29 13:51:20 tron Exp $
fields[field].text2, pattern);
}
return(NO);
-@@ -555,17 +555,17 @@
+@@ -555,17 +555,17 @@ progress(char *what, long current, long
move(MSGLINE, 0);
clrtoeol();
addstr(what);
@@ -53,7 +62,7 @@ $NetBSD: patch-ai,v 1.4 2006/05/29 13:51:20 tron Exp $
}
start = now;
-@@ -603,7 +603,7 @@
+@@ -603,7 +603,7 @@ myperror(char *text)
s = sys_errlist[errno];
}
#endif
diff --git a/devel/cscope/patches/patch-aj b/devel/cscope/patches/patch-aj
index fea90578dc0..50ab30ba5bf 100644
--- a/devel/cscope/patches/patch-aj
+++ b/devel/cscope/patches/patch-aj
@@ -1,8 +1,26 @@
-$NetBSD: patch-aj,v 1.2 2006/05/29 13:51:20 tron Exp $
+$NetBSD: patch-aj,v 1.3 2006/08/24 22:02:02 salo Exp $
---- src/edit.c.orig 2001-07-18 14:49:01.000000000 +0100
-+++ src/edit.c 2006-05-29 14:34:26.000000000 +0100
-@@ -105,9 +105,9 @@
+--- src/edit.c.orig 2001-07-18 15:49:01.000000000 +0200
++++ src/edit.c 2006-08-24 23:39:09.000000000 +0200
+@@ -60,7 +60,7 @@ editref(int i)
+ seekline(i + topline);
+
+ /* get the file name and line number */
+- if (fscanf(refsfound, "%s%*s%s", file, linenum) == 2) {
++ if (fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s", file, linenum) == 2) {
+ edit(file, linenum); /* edit it */
+ }
+ seekline(topline); /* restore the line pointer */
+@@ -83,7 +83,7 @@ editall(void)
+ seekline(1);
+
+ /* get each file name and line number */
+- while (fscanf(refsfound, "%s%*s%s%*[^\n]", file, linenum) == 2) {
++ while (fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", file, linenum) == 2) {
+ edit(file, linenum); /* edit it */
+ if (editallprompt == YES) {
+ addstr("Type ^D to stop editing all lines, or any other character to continue: ");
+@@ -105,9 +105,9 @@ edit(char *file, char *linenum)
char *s;
file = filepath(file);
@@ -14,7 +32,7 @@ $NetBSD: patch-aj,v 1.2 2006/05/29 13:51:20 tron Exp $
/* if this is the more or page commands */
if (strcmp(s = mybasename(editor), "more") == 0 || strcmp(s, "page") == 0) {
-@@ -132,7 +132,7 @@
+@@ -132,7 +132,7 @@ filepath(char *file)
static char path[PATHLEN + 1];
if (prependpath != NULL && *file != '/') {
diff --git a/devel/cscope/patches/patch-ap b/devel/cscope/patches/patch-ap
new file mode 100644
index 00000000000..d96fffb59f6
--- /dev/null
+++ b/devel/cscope/patches/patch-ap
@@ -0,0 +1,24 @@
+$NetBSD: patch-ap,v 1.1 2006/08/24 22:02:02 salo Exp $
+
+--- src/input.c.orig 2001-07-18 15:49:01.000000000 +0200
++++ src/input.c 2006-08-24 23:44:25.000000000 +0200
+@@ -290,7 +290,7 @@ shellpath(char *out, int limit, char *in
+ v = logdir(out);
+ }
+ /* copy the directory name */
+- if (v != NULL) {
++ if (v != NULL && strlen(v) < (lastchar - out)) {
+ (void) strcpy(out - 1, v);
+ out += strlen(v) - 1;
+ }
+@@ -313,8 +313,8 @@ shellpath(char *out, int limit, char *in
+ }
+ *s = '\0';
+
+- /* get its value */
+- if ((v = getenv(out)) != NULL) {
++ /* get its value, but only it isn't too big */
++ if ((v = getenv(out)) != NULL && strlen(v) < (lastchar - out)) {
+ (void) strcpy(out - 1, v);
+ out += strlen(v) - 1;
+ }