aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Kennaway <kris@FreeBSD.org>2001-03-03 23:45:43 +0000
committerKris Kennaway <kris@FreeBSD.org>2001-03-03 23:45:43 +0000
commit28ae2e3a2b66b61dfa06a9c7b6450135a95038f3 (patch)
treef4abdc9cc4fe8f868be776baaf9f72d1e7092e58
parent3b6eaa7b1ef31985836f61a8d833b90490c337b5 (diff)
downloadsrc-28ae2e3a2b66b61dfa06a9c7b6450135a95038f3.tar.gz
src-28ae2e3a2b66b61dfa06a9c7b6450135a95038f3.zip
Import vendor fix for buffer overflow in HOME environment variable
Notes
Notes: svn path=/vendor/tcsh/dist/; revision=73393
-rw-r--r--contrib/tcsh/sh.c18
-rw-r--r--contrib/tcsh/sh.dir.c33
2 files changed, 35 insertions, 16 deletions
diff --git a/contrib/tcsh/sh.c b/contrib/tcsh/sh.c
index 088d31099452..0bfa2564bf20 100644
--- a/contrib/tcsh/sh.c
+++ b/contrib/tcsh/sh.c
@@ -528,14 +528,26 @@ main(argc, argv)
*/
shlvl(1);
- if ((tcp = getenv("HOME")) != NULL)
- cp = quote(SAVE(tcp));
- else
+ if ((tcp = getenv("HOME")) != NULL) {
+ if (strlen(tcp) >= MAXPATHLEN) {
+ struct passwd *pw;
+ if ((pw = getpwuid(getuid())) != NULL)
+ cp = quote(SAVE(pw->pw_dir));
+ else {
+ tcp[MAXPATHLEN-1] = '\0';
+ cp = quote(SAVE(tcp));
+ }
+ } else {
+ cp = quote(SAVE(tcp));
+ }
+ } else
cp = NULL;
+
if (cp == NULL)
fast = 1; /* No home -> can't read scripts */
else
set(STRhome, cp, VAR_READWRITE);
+
dinit(cp); /* dinit thinks that HOME == cwd in a login
* shell */
/*
diff --git a/contrib/tcsh/sh.dir.c b/contrib/tcsh/sh.dir.c
index 2b6fe041c66d..fd0adfda5a00 100644
--- a/contrib/tcsh/sh.dir.c
+++ b/contrib/tcsh/sh.dir.c
@@ -814,6 +814,7 @@ dcanon(cp, p)
#ifdef apollo
bool slashslash;
#endif /* apollo */
+ size_t clen;
#ifdef S_IFLNK /* if we have symlinks */
Char link[MAXPATHLEN];
@@ -823,23 +824,34 @@ dcanon(cp, p)
#endif /* S_IFLNK */
/*
- * kim: if the path given is too long abort().
+ * if the path given is too long truncate it!
*/
- if (Strlen(cp) >= MAXPATHLEN)
- abort();
+ if ((clen = Strlen(cp)) >= MAXPATHLEN)
+ cp[clen = MAXPATHLEN - 1] = '\0';
/*
* christos: if the path given does not start with a slash prepend cwd. If
- * cwd does not start with a slash or the result would be too long abort().
+ * cwd does not start with a slash or the result would be too long try to
+ * correct it.
*/
if (!ABSOLUTEP(cp)) {
Char tmpdir[MAXPATHLEN];
+ size_t len;
p1 = varval(STRcwd);
- if (p1 == STRNULL || !ABSOLUTEP(p1))
- abort();
- if (Strlen(p1) + Strlen(cp) + 1 >= MAXPATHLEN)
- abort();
+ if (p1 == STRNULL || !ABSOLUTEP(p1)) {
+ char *tmp = (char *)getcwd((char *)tmpdir, sizeof(tmpdir));
+ if (tmp == NULL || *tmp == '\0') {
+ xprintf("%s: %s\n", progname, strerror(errno));
+ set(STRcwd, SAVE("/"), VAR_READWRITE|VAR_NOGLOB);
+ } else {
+ set(STRcwd, SAVE(tmp), VAR_READWRITE|VAR_NOGLOB);
+ }
+ p1 = varval(STRcwd);
+ }
+ len = Strlen(p1);
+ if (len + clen + 1 >= MAXPATHLEN)
+ cp[MAXPATHLEN - (len + 1)] = '\0';
(void) Strcpy(tmpdir, p1);
(void) Strcat(tmpdir, STRslash);
(void) Strcat(tmpdir, cp);
@@ -847,11 +859,6 @@ dcanon(cp, p)
cp = p = Strsave(tmpdir);
}
-#ifdef COMMENT
- if (*cp != '/')
- abort();
-#endif /* COMMENT */
-
#ifdef apollo
slashslash = (cp[0] == '/' && cp[1] == '/');
#endif /* apollo */