[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
user/2393: Dangerous string operations in mg
- To: gnats@openbsd.org
- Subject: user/2393: Dangerous string operations in mg
- From: Vincent Labrecque <limitln@psyfreaks.ca>
- Date: 10 Feb 2002 22:33:45 -0500
- Resent-Date: Mon, 11 Feb 2002 20:40:02 -0700 (MST)
- Resent-From: gnats@cvs.openbsd.org (GNATS Management)
- Resent-Message-Id: <200202120340.g1C3e27N022407@cvs.openbsd.org>
- Resent-Reply-To: gnats@cvs.openbsd.org,Received: "from openbsd.cs.colorado.edu (openbsd.cs.colorado.edu [128.138.192.83]) by cvs.openbsd.org (8.12.2/8.12.1) with ESMTP id g1C3c9WV014477 (version=TLSv1/SSLv3 cipher=EDH-DSS-DES-CBC3-SHA bits=168 verify=FAIL) for" <gnats@cvs.openbsd.org>;,Mon@naughty.monkey.org, 11@naughty.monkey.org,Feb@naughty.monkey.org, 2002@naughty.monkey.org,20:38:10.-0700@cvs.openbsd.org (MST)
- Resent-To: bugs@cvs.openbsd.org
>Number: 2393
>Category: user
>Synopsis: mg does a few unsafe string operations (str{,n}{cpy,cat})
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bugs
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Feb 11 20:40:01 MST 2002
>Last-Modified:
>Originator: Vincent Labrecque
>Organization:
None
>Release: OpenBSD 3.0-current
>Environment:
<machine, os, target, libraries (multiple lines)>
System : OpenBSD 3.0
Architecture: OpenBSD.i386
Machine : i386
>Description:
<precise description of the problem (multiple lines)>
There isn't much to say.
Mg does a few strcpy and strcat calls. Just fix them.
At the same time, I simplified some parts of the code (definekey()).
>How-To-Repeat:
<code/input/activities to reproduce the problem (multiple lines)>
read the mg code
>Fix:
Look at and alpply this diff.
Common subdirectories: /sources/src/usr.bin/mg/CVS and /sources/lsrc/usr.bin/mg/CVS
diff -u /sources/src/usr.bin/mg/buffer.c /sources/lsrc/usr.bin/mg/buffer.c
--- /sources/src/usr.bin/mg/buffer.c Sat Jan 26 16:02:53 2002
+++ /sources/lsrc/usr.bin/mg/buffer.c Sun Feb 10 17:59:56 2002
@@ -453,7 +453,7 @@
} while (i++ < defb_nmodes);
bp->b_fname[0] = '\0';
bzero(&bp->b_fi, sizeof(bp->b_fi));
- (void) strcpy(bp->b_bname, bname);
+ (void) strlcpy(bp->b_bname, bname, sizeof bp->b_bname);
lp->l_fp = lp;
lp->l_bp = lp;
bp->b_bufp = bheadp;
diff -u /sources/src/usr.bin/mg/def.h /sources/lsrc/usr.bin/mg/def.h
--- /sources/src/usr.bin/mg/def.h Sat Jan 26 16:02:53 2002
+++ /sources/lsrc/usr.bin/mg/def.h Sun Feb 10 17:58:04 2002
@@ -573,7 +573,7 @@
extern int defb_flag;
extern const char cinfo[];
extern char *keystrings[];
-extern char pat[];
+extern char pat[NPAT];
#ifndef NO_DPROMPT
extern char prompt[];
#endif /* !NO_DPROMPT */
diff -u /sources/src/usr.bin/mg/dir.c /sources/lsrc/usr.bin/mg/dir.c
--- /sources/src/usr.bin/mg/dir.c Wed May 23 22:05:21 2001
+++ /sources/lsrc/usr.bin/mg/dir.c Sun Feb 10 17:37:14 2002
@@ -38,7 +38,7 @@
if ((s = ereply("Change default directory: ", bufc, NPAT)) != TRUE)
return (s);
if (bufc[0] == '\0')
- (void) strcpy(bufc, wdir);
+ (void) strlcpy(bufc, wdir, sizeof bufc);
if (chdir(bufc) == -1) {
ewprintf("Can't change dir to %s", bufc);
return (FALSE);
diff -u /sources/src/usr.bin/mg/echo.c /sources/lsrc/usr.bin/mg/echo.c
--- /sources/src/usr.bin/mg/echo.c Sat Jan 26 16:02:54 2002
+++ /sources/lsrc/usr.bin/mg/echo.c Sun Feb 10 22:11:23 2002
@@ -429,113 +429,111 @@
if (bclear(bp) == FALSE)
return FALSE;
- { /* this {} present for historical reasons */
-
+ /*
+ * first get the list of objects. This list may contain only
+ * the ones that complete what has been typed, or may be the
+ * whole list of all objects of this type. They are filtered
+ * later in any case. Set wholelist if the list has been
+ * cons'ed up just for us, so we can free it later. We have
+ * to copy the buffer list for this function even though we
+ * didn't for complt. The sorting code does destructive
+ * changes to the list, which we don't want to happen to the
+ * main buffer list!
+ */
+ if ((flags & EFBUF) != 0)
+ wholelist = lh = copy_list(&(bheadp->b_list));
+ else if ((flags & EFFUNC) != 0) {
+ buf[cpos] = '\0';
+ wholelist = lh = complete_function_list(buf, c);
+ } else if ((flags & EFFILE) != 0) {
+ buf[cpos] = '\0';
+ wholelist = lh = make_file_list(buf);
/*
- * first get the list of objects. This list may contain only
- * the ones that complete what has been typed, or may be the
- * whole list of all objects of this type. They are filtered
- * later in any case. Set wholelist if the list has been
- * cons'ed up just for us, so we can free it later. We have
- * to copy the buffer list for this function even though we
- * didn't for complt. The sorting code does destructive
- * changes to the list, which we don't want to happen to the
- * main buffer list!
- */
- if ((flags & EFBUF) != 0)
- wholelist = lh = copy_list(&(bheadp->b_list));
- else if ((flags & EFFUNC) != 0) {
- buf[cpos] = '\0';
- wholelist = lh = complete_function_list(buf, c);
- } else if ((flags & EFFILE) != 0) {
- buf[cpos] = '\0';
- wholelist = lh = make_file_list(buf);
- /*
* We don't want to display stuff up to the / for file
* names preflen is the list of a prefix of what the
* user typed that should not be displayed.
*/
- cp = strrchr(buf, '/');
- if (cp)
- preflen = cp - buf + 1;
- } else
- panic("broken complt call: flags");
-
+ cp = strrchr(buf, '/');
+ if (cp)
+ preflen = cp - buf + 1;
+ } else
+ panic("broken complt call: flags");
- /*
- * Sort the list, since users expect to see it in alphabetic
- * order.
- */
- lh2 = lh;
- while (lh2) {
- lh3 = lh2->l_next;
- while (lh3) {
- if (strcmp(lh2->l_name, lh3->l_name) > 0) {
- cp = lh2->l_name;
- lh2->l_name = lh3->l_name;
- lh3->l_name = cp;
- }
- lh3 = lh3->l_next;
+
+ /*
+ * Sort the list, since users expect to see it in alphabetic
+ * order.
+ */
+ lh2 = lh;
+ while (lh2) {
+ lh3 = lh2->l_next;
+ while (lh3) {
+ if (strcmp(lh2->l_name, lh3->l_name) > 0) {
+ cp = lh2->l_name;
+ lh2->l_name = lh3->l_name;
+ lh3->l_name = cp;
}
- lh2 = lh2->l_next;
+ lh3 = lh3->l_next;
}
+ lh2 = lh2->l_next;
+ }
- /*
- * First find max width of object to be displayed, so we can
- * put several on a line.
- */
- maxwidth = 0;
- lh2 = lh;
- while (lh2 != NULL) {
- for (i = 0; i < cpos; ++i) {
- if (buf[i] != lh2->l_name[i])
- break;
- }
- if (i == cpos) {
- width = strlen(lh2->l_name);
- if (width > maxwidth)
- maxwidth = width;
- }
- lh2 = lh2->l_next;
+ /*
+ * First find max width of object to be displayed, so we can
+ * put several on a line.
+ */
+ maxwidth = 0;
+ lh2 = lh;
+ while (lh2 != NULL) {
+ for (i = 0; i < cpos; ++i) {
+ if (buf[i] != lh2->l_name[i])
+ break;
}
- maxwidth += 1 - preflen;
+ if (i == cpos) {
+ width = strlen(lh2->l_name);
+ if (width > maxwidth)
+ maxwidth = width;
+ }
+ lh2 = lh2->l_next;
+ }
+ maxwidth += 1 - preflen;
- /*
- * Now do the display. objects are written into linebuf until
- * it fills, and then put into the help buffer.
- */
- if ((linebuf = malloc((nrow + 1) * sizeof(char))) == NULL)
- return FALSE;
- cp = linebuf;
- width = 0;
- lh2 = lh;
- while (lh2 != NULL) {
- for (i = 0; i < cpos; ++i) {
- if (buf[i] != lh2->l_name[i])
- break;
- }
- if (i == cpos) {
- if ((width + maxwidth) > ncol) {
- *cp = 0;
- addline(bp, linebuf);
- cp = linebuf;
- width = 0;
- }
- strcpy(cp, lh2->l_name + preflen);
- i = strlen(lh2->l_name + preflen);
- cp += i;
- for (; i < maxwidth; i++)
- *cp++ = ' ';
- width += maxwidth;
- }
- lh2 = lh2->l_next;
+ /*
+ * Now do the display. objects are written into linebuf until
+ * it fills, and then put into the help buffer.
+ */
+ if ((linebuf = malloc((nrow + 1) * sizeof(char))) == NULL)
+ return FALSE;
+ cp = linebuf;
+ width = 0;
+ lh2 = lh;
+ while (lh2 != NULL) {
+ for (i = 0; i < cpos; ++i) {
+ if (buf[i] != lh2->l_name[i])
+ break;
}
- if (width > 0) {
- *cp = 0;
- addline(bp, linebuf);
+ if (i == cpos) {
+ if ((width + maxwidth) > ncol) {
+ *cp = '\0';
+ addline(bp, linebuf);
+ cp = linebuf;
+ width = 0;
+ }
+ strcpy(cp, lh2->l_name + preflen);
+ i = strlen(lh2->l_name + preflen);
+ cp += i;
+ for (; i < maxwidth; i++)
+ *cp++ = ' ';
+ width += maxwidth;
}
- free(linebuf);
+ lh2 = lh2->l_next;
+ }
+ if (width > 0) {
+ *cp = 0;
+ addline(bp, linebuf);
}
+ free(linebuf);
+
/*
* Note that we free lists only if they are put in wholelist lists
* that were built just for us should be freed. However when we use
diff -u /sources/src/usr.bin/mg/extend.c /sources/lsrc/usr.bin/mg/extend.c
--- /sources/src/usr.bin/mg/extend.c Thu Jul 5 12:36:05 2001
+++ /sources/lsrc/usr.bin/mg/extend.c Sun Feb 10 22:14:11 2002
@@ -495,20 +495,22 @@
*/
/* ARGSUSED */
int
-define_key(f, n)
- int f, n;
+define_key(int f, int n)
{
- static char buf[48] = "Define key map: ";
- KEYMAP *mp;
+ static char buf[48];
+ char tmp[32];
+ KEYMAP *mp;
- buf[16] = '\0';
- if (eread(buf, &buf[16], 48 - 16, EFNEW) != TRUE)
+ strlcpy(buf, "Define key map: ", sizeof buf);
+ if (eread(buf, tmp, sizeof tmp, EFNEW) != TRUE)
return FALSE;
- if ((mp = name_map(&buf[16])) == NULL) {
- ewprintf("Unknown map %s", &buf[16]);
+ strlcat(buf, tmp, sizeof buf);
+ if ((mp = name_map(tmp)) == NULL) {
+ ewprintf("Unknown map %s", tmp);
return FALSE;
}
- (void)strncat(&buf[16], " key: ", 48 - 16 - 1);
+ strlcat(buf, "key: ", sizeof buf);
+
return dobind(mp, buf, FALSE);
}
diff -u /sources/src/usr.bin/mg/file.c /sources/lsrc/usr.bin/mg/file.c
--- /sources/src/usr.bin/mg/file.c Wed May 23 22:05:22 2001
+++ /sources/lsrc/usr.bin/mg/file.c Sun Feb 10 18:01:01 2002
@@ -95,7 +95,7 @@
char *fname;
{
BUFFER *bp;
- char bname[NBUFN], *cp;
+ char bname[NBUFN];
unsigned int count = 1;
for (bp = bheadp; bp != NULL; bp = bp->b_bufp) {
@@ -103,10 +103,10 @@
return bp;
}
/* new buffer name */
- strcpy(bname, basename(fname));
- cp = bname + strlen(bname);
for (count = 1; bfind(bname, FALSE) != NULL; count++)
- sprintf(cp, "<%d>", count);
+ ;
+ snprintf(bname, sizeof bname, "%s%d", basename(fname), count);
+
return bfind(bname, TRUE);
}
@@ -182,7 +182,7 @@
/* cheap */
bp = curbp;
if (newname != NULL)
- (void)strcpy(bp->b_fname, newname);
+ (void)strlcpy(bp->b_fname, newname, sizeof bp->b_fname);
/* hard file open */
if ((s = ffropen(fname, needinfo ? bp : NULL)) == FIOERR)
@@ -340,7 +340,7 @@
/* old attributes are no longer current */
bzero(&curbp->b_fi, sizeof(curbp->b_fi));
if ((s = writeout(curbp, adjfname)) == TRUE) {
- (void)strcpy(curbp->b_fname, adjfname);
+ (void)strlcpy(curbp->b_fname, adjfname, sizeof curbp->b_fname);
#ifndef NO_BACKUP
curbp->b_flag &= ~(BFBAK | BFCHG);
#else /* !NO_BACKUP */
diff -u /sources/src/usr.bin/mg/re_search.c /sources/lsrc/usr.bin/mg/re_search.c
--- /sources/src/usr.bin/mg/re_search.c Wed May 23 22:05:25 2001
+++ /sources/lsrc/usr.bin/mg/re_search.c Sun Feb 10 18:01:46 2002
@@ -430,7 +430,7 @@
if (s == TRUE) {
/* New pattern given */
- (void)strcpy(re_pat, tpat);
+ (void)strlcpy(re_pat, tpat, sizeof re_pat);
if (casefoldsearch)
flags = REG_EXTENDED | REG_ICASE;
else
diff -u /sources/src/usr.bin/mg/region.c /sources/lsrc/usr.bin/mg/region.c
--- /sources/src/usr.bin/mg/region.c Wed May 23 22:05:26 2001
+++ /sources/lsrc/usr.bin/mg/region.c Sun Feb 10 18:01:59 2002
@@ -298,7 +298,7 @@
s = ereply("Prefix string (default %s): ",
buf, sizeof buf, prefix_string);
if (s == TRUE)
- (void)strcpy(prefix_string, buf);
+ (void)strlcpy(prefix_string, buf, sizeof prefix_string);
/* CR -- use old one */
if ((s == FALSE) && (prefix_string[0] != '\0'))
s = TRUE;
diff -u /sources/src/usr.bin/mg/search.c /sources/lsrc/usr.bin/mg/search.c
--- /sources/src/usr.bin/mg/search.c Wed May 23 22:05:26 2001
+++ /sources/lsrc/usr.bin/mg/search.c Sun Feb 10 17:57:51 2002
@@ -175,7 +175,7 @@
for (cip = 0; cip < NSRCH; cip++)
cmds[cip].s_code = SRCH_NOPR;
- (void)strcpy(opat, pat);
+ (void)strlcpy(opat, pat, sizeof opat);
cip = 0;
pptr = -1;
clp = curwp->w_dotp;
@@ -216,7 +216,7 @@
curwp->w_flag |= WFMOVE;
srch_lastdir = dir;
(void)ctrlg(FFRAND, 0);
- (void)strcpy(pat, opat);
+ (void)strlcpy(pat, opat, sizeof pat);
return ABORT;
case CCHR(']'):
case CCHR('S'):
@@ -689,7 +689,7 @@
/* specified */
if (s == TRUE)
- (void) strcpy(pat, tpat);
+ (void) strlcpy(pat, tpat, sizeof pat);
/* CR, but old one */
else if (s == FALSE && pat[0] != 0)
s = TRUE;
>Audit-Trail:
>Unformatted: