From owner-freebsd-ports-bugs@FreeBSD.ORG Tue Dec 13 00:30:09 2005 Return-Path: X-Original-To: freebsd-ports-bugs@hub.freebsd.org Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0954916A41F for ; Tue, 13 Dec 2005 00:30:09 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2D1ED43D5C for ; Tue, 13 Dec 2005 00:30:07 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id jBD0U6rn024795 for ; Tue, 13 Dec 2005 00:30:07 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id jBD0U6em024794; Tue, 13 Dec 2005 00:30:06 GMT (envelope-from gnats) Resent-Date: Tue, 13 Dec 2005 00:30:06 GMT Resent-Message-Id: <200512130030.jBD0U6em024794@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Juergen Lock Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B711316A41F for ; Tue, 13 Dec 2005 00:25:57 +0000 (GMT) (envelope-from nox@saturn.kn-bremen.de) Received: from gwyn.kn-bremen.de (gwyn.kn-bremen.de [212.63.36.242]) by mx1.FreeBSD.org (Postfix) with ESMTP id 838E543D5A for ; Tue, 13 Dec 2005 00:25:52 +0000 (GMT) (envelope-from nox@saturn.kn-bremen.de) Received: from gwyn.kn-bremen.de (gwyn [127.0.0.1]) by gwyn.kn-bremen.de (8.13.4/8.13.4/Debian-3) with ESMTP id jBD0PprT013175 for ; Tue, 13 Dec 2005 01:25:51 +0100 Received: from saturn.kn-bremen.de (uucp@localhost) by gwyn.kn-bremen.de (8.13.4/8.13.4/Submit) with UUCP id jBD0PpLB013173 for FreeBSD-gnats-submit@freebsd.org; Tue, 13 Dec 2005 01:25:51 +0100 Received: from saturn.kn-bremen.de (localhost [127.0.0.1]) by saturn.kn-bremen.de (8.13.1/8.13.1) with ESMTP id jBD0Li6m075057 for ; Tue, 13 Dec 2005 01:21:44 +0100 (CET) (envelope-from nox@saturn.kn-bremen.de) Received: (from nox@localhost) by saturn.kn-bremen.de (8.13.1/8.13.1/Submit) id jBD0Lh3Q075056; Tue, 13 Dec 2005 01:21:43 +0100 (CET) (envelope-from nox) Message-Id: <200512130021.jBD0Lh3Q075056@saturn.kn-bremen.de> Date: Tue, 13 Dec 2005 01:21:43 +0100 (CET) From: Juergen Lock To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: ports/90317: buffer overflows in www/gnuinfo X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Juergen Lock List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Dec 2005 00:30:09 -0000 >Number: 90317 >Category: ports >Synopsis: buffer overflows in www/gnuinfo >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: maintainer-update >Submitter-Id: current-users >Arrival-Date: Tue Dec 13 00:30:06 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Juergen Lock >Release: FreeBSD 5.3-RELEASE-p20 i386 >Organization: me? organized?? >Environment: System: FreeBSD saturn 5.3-RELEASE-p20 FreeBSD 5.3-RELEASE-p20 #1: Fri Jul 29 14:59:03 CEST 2005 nox@saturn:/usr/home/nox/src5/usr/src/sys/i386/compile/NEPTUN i386 >Description: Per advice of kris@ I post the security patch, in the hope that the port will be added to vuxml soon. (I hope the disappeared MASTER_SITE can be taken care of after that.) Security: try to fix possible buffer overflows or similar. >How-To-Repeat: hmm, look at the code? :) >Fix: New file: files/patch-security Index: files/patch-security @@ -0,0 +1,315 @@ +Index: convert.lex +@@ -140,50 +140,66 @@ + + void print_longlink(char *link) + { +- char linknode[LINK_LENGTH]; ++ char linknode[LINK_LENGTH * 3]; + char linkfile[LINK_LENGTH]; + char text[LINK_LENGTH]; + char *h; + + /* text */ +- strcpy(text,link+(link[1]==' ' ? 2 : 6)); +- *(strchr(text,':')) = '\0'; ++ snprintf(text, sizeof text, "%s", link+(link[1]==' ' ? 2 : 6)); ++ h = strchr(text,':'); ++ if (h) *h = '\0'; + + /* link */ + h = strchr(link,':'); + do h++; while (*h == ' '); + if (*h == '(') { + /* we have a file */ +- strcpy(linkfile,h+1); +- *(h=strchr(linkfile,')')) = '\0'; +- do h++; while (*h == ' '); ++ if (strlen(h) > sizeof linkfile) { ++ snprintf(linkfile, sizeof linkfile, "%s", file); ++ h = NULL; ++ } else { ++ snprintf(linkfile, sizeof linkfile, "%s", h+1); ++ h=strchr(linkfile,')'); ++ if (h) *h = '\0'; ++ } ++ if (h) { ++ do h++; while (*h == ' '); ++ } + strcpy(linknode,"Top"); /* default node, may be overwritten later */ + } else { +- strcpy(linkfile,file); ++ snprintf(linkfile, sizeof linkfile, "%s", file); + } +- if (*h != '.' && *h != ',') { ++ if (h && *h != '.' && *h != ',' && strlen(h) * 3 < sizeof linknode - 1) { + /* we have a node */ +- quote(linknode,h); ++ quote(linknode, sizeof linknode, h); + h = strstr(linknode,"%2e"); /* quoted '.' */ + if (!h) + h = strstr(linknode,"%2c"); /* quoted ',' */ +- *h = '\0'; ++ if (h) *h = '\0'; + } + printf("*",whoami,linkfile,linknode); + if (link[1] != ' ') printf("note"); + printf(" %s:",text); + if (link[1] == ' ') printf(MENU_DESC); + h = strchr(link,':'); +- do h++; while (*h == ' '); +- printf("%s",h); ++ if (h) { ++ do h++; while (*h == ' '); ++ printf("%s",h); ++ } + } + + void print_shortlink(char *link) + { +- char linknode[LINK_LENGTH]; ++ char linknode[LINK_LENGTH * 3], *h; + +- quote(linknode,link+(link[1]==' ' ? 2 : 6)); +- *(strstr(linknode,"%3a")) = '\0'; /* ':' -> "%3a" (URL-Quoting) */ ++ if (strlen(link) * 3 > sizeof linknode - 1) ++ strcpy(linknode, "Top"); ++ else { ++ quote(linknode, sizeof linknode, link+(link[1]==' ' ? 2 : 6)); ++ h = strstr(linknode,"%3a"); ++ if (h) *h = '\0'; /* ':' -> "%3a" (URL-Quoting) */ ++ } + + printf("",whoami,file,linknode); + printf("%s",link); +Index: info2html.c +@@ -22,12 +22,12 @@ + + /*-------------------------------------------------------------*/ + +-void quote(char *dest, char *src) ++void quote(char *dest, size_t bufsize, char *src) + { + static const char lookup[16] = "0123456789abcdef"; + int i,j; + +- for (i=0, j=0; src[j] != '\0';) { ++ for (i=0, j=0; src[j] != '\0' && i < bufsize - 4 ;) { + if (isalnum(src[j])) { + dest[i++] = src[j++]; + } else { +@@ -41,12 +41,12 @@ + } + + /* copy string and convert the "%??" to normal char's */ +-void unquote(char *dest, char *src) ++void unquote(char *dest, size_t bufsize, char *src) + { + int i,j,hex; + char nr[3]; + +- for (i=0, j=0; src[j] != '?' && src[j] != '\0'; i++) { ++ for (i=0, j=0; src[j] != '?' && src[j] != '\0' && i < bufsize - 1 ; i++) { + if (src[j] == '%') { + nr[0] = src[j+1]; + nr[1] = src[j+2]; +@@ -72,12 +72,12 @@ + file[0] = 0; + node[0] = 0; + path = getenv("PATH_INFO"); +- if (path && *path) { +- strcpy(file,path+1); ++ if (path && *path && strlen(path) < sizeof file) { ++ snprintf(file, sizeof file, "%s", path+1); + h = strchr(file,'/'); + if (h) { + *(h++) = 0; +- if (*h) strcpy(node,h); ++ if (*h) snprintf(node, sizeof node, "%s", h); + /* workaround: Spinner appends a slash to the URL */ + if (NULL != (h = strchr(node,'/'))) *h = 0; + } +@@ -100,11 +100,13 @@ + h++; + } + } +- strcpy(whoami,h); ++ if (strlen(h) >= sizeof whoami) ++ h = argv0; ++ snprintf(whoami, sizeof whoami, "%s", h); + } + + /*-------------------------------------------------------------*/ +- ++ + char infodirs[]=INFODIRS; + char *dirs[20]; + +@@ -119,7 +121,7 @@ + else + dirs[0] = infodirs; + +- for (i = 0; dirs[i] != NULL ; i++) { ++ for (i = 0; dirs[i] != NULL && i < sizeof dirs - 1; i++) { + h = strchr(dirs[i],':'); + if (h) { + *h = 0; +@@ -135,7 +137,7 @@ + /* open an infofile. The indir-parameter is for indirections */ + FILE *open_infofile(int indir) + { +- char filename[LINK_LENGTH],nr[10],last_modi[80]; ++ char *filename = NULL,nr[10],last_modi[80]; + struct stat st; + int fd_pipe[2]; + int i,d,gzip; +@@ -149,29 +151,29 @@ + for (i = 0; i < 4 /* 8 */; i++) { + switch (i) { + case 0: +- gzip = FALSE;sprintf(filename,"%s/%s%s",dirs[d],file,nr); ++ gzip = FALSE;asprintf(&filename,"%s/%s%s",dirs[d],file,nr); + break; + case 1: +- gzip = FALSE;sprintf(filename,"%s/%s.info%s",dirs[d],file,nr); ++ gzip = FALSE;asprintf(&filename,"%s/%s.info%s",dirs[d],file,nr); + break; + case 2: +- gzip = TRUE; sprintf(filename,"%s/%s%s.gz",dirs[d],file,nr); ++ gzip = TRUE; asprintf(&filename,"%s/%s%s.gz",dirs[d],file,nr); + break; + case 3: +- gzip = TRUE; sprintf(filename,"%s/%s.info%s.gz",dirs[d],file,nr); ++ gzip = TRUE; asprintf(&filename,"%s/%s.info%s.gz",dirs[d],file,nr); + break; + /* + case 4: +- gzip = TRUE; sprintf(filename,"%s/%s%s.z",dirs[d],file,nr); ++ gzip = TRUE; asprintf(&filename,"%s/%s%s.z",dirs[d],file,nr); + break; + case 5: +- gzip = TRUE; sprintf(filename,"%s/%s.info%s.z",dirs[d],file,nr); ++ gzip = TRUE; asprintf(&filename,"%s/%s.info%s.z",dirs[d],file,nr); + break; + case 6: +- gzip = TRUE; sprintf(filename,"%s/%s%s.Z",dirs[d],file,nr); ++ gzip = TRUE; asprintf(&filename,"%s/%s%s.Z",dirs[d],file,nr); + break; + case 7: +- gzip = TRUE; sprintf(filename,"%s/%s.info%s.Z",dirs[d],file,nr); ++ gzip = TRUE; asprintf(&filename,"%s/%s.info%s.Z",dirs[d],file,nr); + break; + */ + default: return NULL; /* keep compiler happy */ +@@ -191,6 +193,7 @@ + pipe(fd_pipe); + switch (fork()) { + case -1: ++ if (filename) free(filename); + return NULL; + case 0: + /* child */ +@@ -204,14 +207,20 @@ + dup2(fd_pipe[0],0); + close(fd_pipe[0]); + close(fd_pipe[1]); ++ if (filename) free(filename); + return stdin; + } + } else { +- return fopen(filename,"r"); ++ if (filename) { ++ FILE *ret = fopen(filename,"r"); ++ free(filename); ++ return ret; ++ } + } + } + } + } ++ if (filename) free(filename); + return NULL; + } + +@@ -221,23 +230,25 @@ + { + char text[LINK_LENGTH]; + char linkfile[LINK_LENGTH]; +- char linknode[LINK_LENGTH]; ++ char linknode[LINK_LENGTH * 3]; + char *h; + ++ if (strlen(buf) >= LINK_LENGTH) return; + h = strstr(buf,what); + if (!h) return; + h += strlen(what); +- strcpy(text,h); ++ snprintf(text, sizeof text, "%s", h); + h = strchr(text,',' ); if (h) *h = '\0'; + h = strchr(text,'\t'); if (h) *h = '\0'; + h = strchr(text,'\n'); if (h) *h = '\0'; + if (text[0] == '(') { +- strcpy(linkfile,text+1); +- *(strchr(linkfile,')')) = '\0'; ++ snprintf(linkfile, sizeof linkfile, "%s", text+1); ++ h = strchr(linkfile,')'); ++ if (h) *h = '\0'; + strcpy(linknode,"Top"); + } else { +- strcpy(linkfile,file); +- quote(linknode,text); ++ snprintf(linkfile, sizeof linkfile, "%s", file); ++ quote(linknode, sizeof linknode, text); + } + printf("%s %s \n", + what,whoami,linkfile,linknode,text); +@@ -249,21 +260,22 @@ + log_error(int node_failed) + { + time_t tm; +- char timestr[64],from[256]; ++ char timestr[64], *from = strdup(""); + + time(&tm); + strftime(timestr,64,"%a %h %d %T %Y", + localtime(&tm)); +- if (getenv("HTTP_REFERER")) /* be sure we have a referer */ +- sprintf(from," from %250s",getenv("HTTP_REFERER")); +- else +- from[0] = 0; ++ if (getenv("HTTP_REFERER")) { /* be sure we have a referer */ ++ free(from); ++ asprintf(&from," from %250s",getenv("HTTP_REFERER")); ++ } + if (node_failed) + fprintf(stderr,"[%s] gnuinfo: access to node %s, info file %s failed%s\n", + timestr,node,file,from); + else + fprintf(stderr,"[%s] gnuinfo: access to info file %s failed%s\n", + timestr,file,from); ++ if (from) free(from); + } + + /*-------------------------------------------------------------*/ +@@ -366,8 +378,11 @@ + } + + /* find out which file */ +- h = strchr(buf,127); h++; +- line = atoi(h); ++ if ((h = strchr(buf,127))) { ++ h++; ++ line = atoi(h); ++ } else ++ line = 0; + for (i = 0; indir_table[i] != 0 && line >= indir_table[i] ; i++); + + /* play it again... */ +Index: info2html.h +@@ -17,5 +17,5 @@ + extern FILE *yyin; + int yylex(); + +-void quote(char*, char*); +-void unquote(char* , char*); ++void quote(char*, size_t bufsize, char*); ++void unquote(char*, size_t bufsize, char*); >Release-Note: >Audit-Trail: >Unformatted: