From shigio@wafu.netgate.net Thu Aug 13 10:50:09 1998 Received: from wafu.netgate.net (wafu.netgate.net [204.145.147.80]) by hub.freebsd.org (8.8.8/8.8.8) with SMTP id KAA07368 for ; Thu, 13 Aug 1998 10:50:06 -0700 (PDT) (envelope-from shigio@wafu.netgate.net) Received: (qmail 22663 invoked from network); 13 Aug 1998 09:50:18 -0000 Received: from ins69.tama-ap3.dti.ne.jp (HELO choota.signet.or.jp) (203.181.67.87) by wafu.netgate.net with SMTP; 13 Aug 1998 09:50:18 -0000 Received: (from shigio@localhost) by choota.signet.or.jp (8.8.7/) id CAA04744; Fri, 14 Aug 1998 02:51:57 +0900 (JST) Message-Id: <199808131750.KAA07368@hub.freebsd.org> Date: Fri, 14 Aug 1998 02:51:57 +0900 (JST) From: shigio@wafu.netgate.net Reply-To: shigio@wafu.netgate.net To: FreeBSD-gnats-submit@freebsd.org Cc: shigio@wafu.netgate.net Subject: GTAGS patch for nvi has posibility of buffer overflow. X-Send-Pr-Version: 3.2 >Number: 7607 >Category: bin >Synopsis: GTAGS patch for nvi has posibility of buffer overflow. >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Aug 13 11:00:00 PDT 1998 >Closed-Date: Sat Aug 21 20:48:52 PDT 1999 >Last-Modified: Sat Aug 21 20:49:29 PDT 1999 >Originator: Shigio Yamaguchi >Release: FreeBSD 2.2.5-RELEASE i386 >Organization: freelance programmer >Environment: All environment. >Description: GTAGS patch for nvi has posibility of buffer overflow. o gtag_slist() - sprintf() brings buffer overflow. o getentry() - insufficient error check and buffer size. >How-To-Repeat: no >Fix: o gtags_slist() - use snprintf() instead of sprintf(). o getentry() - error check added and doesn't use small buffer. Here is a patch for /usr/src/contrib/nvi/ex/ex_tag.c. (FreeBSD-current, FreeBSD-stable) *** ex_tag.c.org Fri Aug 14 02:30:36 1998 --- ex_tag.c Fri Aug 14 02:32:22 1998 *************** *** 47,53 **** static void ctag_file __P((SCR *, TAGF *, char *, char **, size_t *)); static int ctag_search __P((SCR *, char *, size_t, char *)); #ifdef GTAGS ! static int getentry __P((char *, char *, char *, char *)); static TAGQ *gtag_slist __P((SCR *, char *, int)); #endif static int ctag_sfile __P((SCR *, TAGF *, TAGQ *, char *)); --- 47,53 ---- static void ctag_file __P((SCR *, TAGF *, char *, char **, size_t *)); static int ctag_search __P((SCR *, char *, size_t, char *)); #ifdef GTAGS ! static int getentry __P((char *, char **, char **, char **)); static TAGQ *gtag_slist __P((SCR *, char *, int)); #endif static int ctag_sfile __P((SCR *, TAGF *, TAGQ *, char *)); *************** *** 1013,1042 **** */ static int getentry(buf, tag, file, line) ! char *buf, *tag, *file, *line; { ! char *p; ! p = tag; ! while (*buf && !isspace(*buf)) /* tag name */ ! *p++ = *buf++; ! *p = 0; ! while (*buf && isspace(*buf)) /* skip blanks */ ! buf++; ! p = line; ! while (*buf && !isspace(*buf)) /* line no */ ! *p++ = *buf++; ! *p = 0; ! while (*buf && isspace(*buf)) /* skip blanks */ ! buf++; ! p = file; ! while (*buf && !isspace(*buf)) /* file name */ ! *p++ = *buf++; *p = 0; /* value check */ ! if (strlen(tag) && strlen(line) && strlen(file) && atoi(line) > 0) return 1; /* OK */ return 0; /* ERROR */ } --- 1013,1052 ---- */ static int getentry(buf, tag, file, line) ! char *buf, **tag, **file, **line; { ! char *p = buf; ! for (*tag = p; *p && !isspace(*p); p++) /* tag name */ ! ; ! if (*p == 0) ! goto err; ! *p++ = 0; ! for (; *p && isspace(*p); p++) /* (skip blanks) */ ! ; ! if (*p == 0) ! goto err; ! *line = p; /* line no */ ! for (*line = p; *p && !isspace(*p); p++) ! ; ! if (*p == 0) ! goto err; ! *p++ = 0; ! for (; *p && isspace(*p); p++) /* (skip blanks) */ ! ; ! if (*p == 0) ! goto err; ! *file = p; /* file name */ ! for (*file = p; *p && !isspace(*p); p++) ! ; ! if (*p == 0) ! goto err; *p = 0; /* value check */ ! if (strlen(*tag) && strlen(*line) && strlen(*file) && atoi(*line) > 0) return 1; /* OK */ + err: return 0; /* ERROR */ } *************** *** 1056,1064 **** size_t len; int echk; TAG *tp; ! static char name[80], file[200], line[10]; ! char command[200]; ! char buf[BUFSIZ+1]; FILE *fp; /* Allocate and initialize the tag queue structure. */ --- 1066,1074 ---- size_t len; int echk; TAG *tp; ! char *name, *file, *line; ! char command[BUFSIZ]; ! char buf[BUFSIZ]; FILE *fp; /* Allocate and initialize the tag queue structure. */ *************** *** 1072,1078 **** * Find the tag, only display missing file messages once, and * then only if we didn't find the tag. */ ! sprintf(command, "global -%s '%s'", ref ? "rx" : "x", tag); if (fp = popen(command, "r")) { while (fgets(buf, sizeof(buf), fp)) { if (buf[strlen(buf)-1] == '\n') /* chop(buf) */ --- 1082,1088 ---- * Find the tag, only display missing file messages once, and * then only if we didn't find the tag. */ ! snprintf(command, sizeof(command), "global -%s '%s'", ref ? "rx" : "x", tag); if (fp = popen(command, "r")) { while (fgets(buf, sizeof(buf), fp)) { if (buf[strlen(buf)-1] == '\n') /* chop(buf) */ *************** *** 1080,1086 **** else while (fgetc(fp) != '\n') ; ! if (getentry(buf, name, file, line) == 0) { echk = 1; F_SET(tfp, TAGF_ERR); break; --- 1090,1096 ---- else while (fgetc(fp) != '\n') ; ! if (getentry(buf, &name, &file, &line) == 0) { echk = 1; F_SET(tfp, TAGF_ERR); break; >Release-Note: >Audit-Trail: State-Changed-From-To: open->closed State-Changed-By: hoek State-Changed-When: Sat Aug 21 20:48:52 PDT 1999 State-Changed-Why: Patch committed to -current. I hope to merge it in time for 3.3-release. >Unformatted: