svn commit: r377324 - in head/www/thttpd: . files
Alexey Dokuchaev
danfe at FreeBSD.org
Sun Jan 18 12:01:20 UTC 2015
Author: danfe
Date: Sun Jan 18 12:01:18 2015
New Revision: 377324
URL: https://svnweb.freebsd.org/changeset/ports/377324
QAT: https://qat.redports.org/buildarchive/r377324/
Log:
Bring another several patches from Gentoo and Red Hat (also relevant to the
upcoming 2.26):
- Fix potential buffer overflow in expand_symlinks() function of libhttpd.c
- Better handling of tempfile and additional input validation in htpasswd(1)
- Make sure that the logfile is created or reopened as read/write by thttpd
(www) user only (modified to allow group read access as well so web admin
won't have to su(1) to super-user or "www" to be able to read logs) [1]
Bump port revision to account for these and previous changes.
Gentoo bug: 458896 [1]
Security: CVE-2013-0348 [1]
Added:
head/www/thttpd/files/patch-extras_htpasswd.c (contents, props changed)
Modified:
head/www/thttpd/Makefile
head/www/thttpd/files/patch-libhttpd.c
head/www/thttpd/files/patch-thttpd.c
Modified: head/www/thttpd/Makefile
==============================================================================
--- head/www/thttpd/Makefile Sun Jan 18 11:40:01 2015 (r377323)
+++ head/www/thttpd/Makefile Sun Jan 18 12:01:18 2015 (r377324)
@@ -3,7 +3,7 @@
PORTNAME= thttpd
PORTVERSION= 2.25b
-PORTREVISION= 5
+PORTREVISION= 6
CATEGORIES= www ipv6
MASTER_SITES= http://www.acme.com/software/thttpd/ \
http://atreides.freenix.no/~anders/
Added: head/www/thttpd/files/patch-extras_htpasswd.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/www/thttpd/files/patch-extras_htpasswd.c Sun Jan 18 12:01:18 2015 (r377324)
@@ -0,0 +1,201 @@
+--- extras/htpasswd.c.orig 2001-12-19 00:08:08 UTC
++++ extras/htpasswd.c
+@@ -21,7 +21,12 @@ extern char *crypt(const char *key, cons
+ #define LF 10
+ #define CR 13
+
++#define CPW_LEN 13
++
++/* ie 'string' + '\0' */
+ #define MAX_STRING_LEN 256
++/* ie 'maxstring' + ':' + cpassword */
++#define MAX_LINE_LEN MAX_STRING_LEN+1+CPW_LEN
+
+ int tfd;
+ char temp_template[] = "/tmp/htp.XXXXXX";
+@@ -137,8 +142,9 @@ add_password( char* user, FILE* f )
+ }
+
+ static void usage(void) {
+- fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n");
+- fprintf(stderr,"The -c flag creates a new file.\n");
++ fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n"
++ "The -c flag creates a new file.\n"
++ "Will prompt for password, unless given on stdin.\n");
+ exit(1);
+ }
+
+@@ -151,51 +157,131 @@ void interrupted(int signo) {
+ int main(int argc, char *argv[]) {
+ FILE *tfp,*f;
+ char user[MAX_STRING_LEN];
+- char line[MAX_STRING_LEN];
+- char l[MAX_STRING_LEN];
++ char pwfilename[MAX_STRING_LEN];
++ char line[MAX_LINE_LEN];
++ char l[MAX_LINE_LEN];
+ char w[MAX_STRING_LEN];
+ char command[MAX_STRING_LEN];
+- int found;
++ int found,u;
+
+ tfd = -1;
++ u = 2; /* argv[u] is username, unless... */
+ signal(SIGINT,(void (*)(int))interrupted);
+ if(argc == 4) {
++ u = 3;
+ if(strcmp(argv[1],"-c"))
+ usage();
++ if((f=fopen(argv[2],"r")) != NULL) {
++ fclose(f);
++ fprintf(stderr,
++ "Password file %s already exists.\n"
++ "Delete it first, if you really want to overwrite it.\n",
++ argv[2]);
++ exit(1);
++ }
++ } else if(argc != 3) usage();
++ /* check uname length; underlying system will take care of pwdfile
++ name too long */
++ if (strlen(argv[u]) >= MAX_STRING_LEN) {
++ fprintf(stderr,"Username too long (max %i): %s\n",
++ MAX_STRING_LEN-1, argv[u]);
++ exit(1);
++ }
++
++ if(argc == 4) {
+ if(!(tfp = fopen(argv[2],"w"))) {
+ fprintf(stderr,"Could not open passwd file %s for writing.\n",
+ argv[2]);
+ perror("fopen");
+ exit(1);
+ }
++ if (strlen(argv[2]) > (sizeof(pwfilename) - 1)) {
++ fprintf(stderr, "%s: filename is too long\n", argv[0]);
++ exit(1);
++ }
++ if (((strchr(argv[2], ';')) != NULL) || ((strchr(argv[2], '>')) != NULL)) {
++ fprintf(stderr, "%s: filename contains an illegal character\n",
++ argv[0]);
++ exit(1);
++ }
++ if (strlen(argv[3]) > (sizeof(user) - 1)) {
++ fprintf(stderr, "%s: username is too long\n", argv[0],
++ sizeof(user) - 1);
++ exit(1);
++ }
++ if ((strchr(argv[3], ':')) != NULL) {
++ fprintf(stderr, "%s: username contains an illegal character\n",
++ argv[0]);
++ exit(1);
++ }
+ printf("Adding password for %s.\n",argv[3]);
+ add_password(argv[3],tfp);
+ fclose(tfp);
+ exit(0);
+- } else if(argc != 3) usage();
++ }
+
+- tfd = mkstemp(temp_template);
+- if(!(tfp = fdopen(tfd,"w"))) {
+- fprintf(stderr,"Could not open temp file.\n");
++ if (strlen(argv[1]) > (sizeof(pwfilename) - 1)) {
++ fprintf(stderr, "%s: filename is too long\n", argv[0]);
++ exit(1);
++ }
++ if (((strchr(argv[1], ';')) != NULL) || ((strchr(argv[1], '>')) != NULL)) {
++ fprintf(stderr, "%s: filename contains an illegal character\n",
++ argv[0]);
++ exit(1);
++ }
++ if (strlen(argv[2]) > (sizeof(user) - 1)) {
++ fprintf(stderr, "%s: username is too long\n", argv[0],
++ sizeof(user) - 1);
++ exit(1);
++ }
++ if ((strchr(argv[2], ':')) != NULL) {
++ fprintf(stderr, "%s: username contains an illegal character\n",
++ argv[0]);
+ exit(1);
+ }
+-
+ if(!(f = fopen(argv[1],"r"))) {
+ fprintf(stderr,
+ "Could not open passwd file %s for reading.\n",argv[1]);
+ fprintf(stderr,"Use -c option to create new one.\n");
+ exit(1);
+ }
++ if(freopen(argv[1],"a",f) == NULL) {
++ fprintf(stderr,
++ "Could not open passwd file %s for writing!.\n"
++ "Changes would be lost.\n",argv[1]);
++ exit(1);
++ }
++ f = freopen(argv[1],"r",f);
++
++ /* pwdfile is there, go on with tempfile now ... */
++ tfd = mkstemp(temp_template);
++ if(!(tfp = fdopen(tfd,"w"))) {
++ fprintf(stderr,"Could not open temp file.\n");
++ exit(1);
++ }
++ /* already checked for boflw ... */
+ strcpy(user,argv[2]);
+
+ found = 0;
+- while(!(getline(line,MAX_STRING_LEN,f))) {
++ /* line we get is username:pwd, or possibly any other cruft */
++ while(!(getline(line,MAX_LINE_LEN,f))) {
++ char *i;
++
+ if(found || (line[0] == '#') || (!line[0])) {
+ putline(tfp,line);
+ continue;
+ }
+- strcpy(l,line);
+- getword(w,l,':');
++ i = index(line,':');
++ w[0] = '\0';
++ /* actually, cpw is CPW_LEN chars and never null, hence ':' should
++ always be at line[strlen(line)-CPW_LEN-1] in a valid user:cpw line
++ Here though we may allow for pre-hancrafted pwdfile (!)...
++ But still need to check for length limits.
++ */
++ if (i != 0 && i-line <= MAX_STRING_LEN-1) {
++ strcpy(l,line);
++ getword(w,l,':');
++ }
+ if(strcmp(user,w)) {
+ putline(tfp,line);
+ continue;
+@@ -210,10 +296,28 @@ int main(int argc, char *argv[]) {
+ printf("Adding user %s\n",user);
+ add_password(user,tfp);
+ }
++ /* close, rewind & copy */
++ fclose(f);
++ fclose(tfp);
++ f = fopen(argv[1],"w");
++ if(f==NULL) {
++ fprintf(stderr,"Failed re-opening %s!?\n",argv[1]);
++ exit(1);
++ }
++ tfp = fopen(temp_template,"r");
++ if(tfp==NULL) {
++ fprintf(stderr,"Failed re-opening tempfile!?\n");
++ exit(1);
++ }
++ {
++ int c;
++ while((c=fgetc(tfp))!=EOF && !feof(tfp)) {
++ fputc(c,f);
++ /* fputc(c,stderr); */
++ }
++ }
+ fclose(f);
+ fclose(tfp);
+- sprintf(command,"cp %s %s",temp_template,argv[1]);
+- system(command);
+ unlink(temp_template);
+ exit(0);
+ }
Modified: head/www/thttpd/files/patch-libhttpd.c
==============================================================================
--- head/www/thttpd/files/patch-libhttpd.c Sun Jan 18 11:40:01 2015 (r377323)
+++ head/www/thttpd/files/patch-libhttpd.c Sun Jan 18 12:01:18 2015 (r377324)
@@ -1,6 +1,24 @@
--- libhttpd.c.orig Mon May 27 01:22:26 2002
+++ libhttpd.c Sun Oct 20 23:49:58 2002
-@@ -3816,6 +3816,9 @@
+@@ -1483,7 +1483,7 @@
+ httpd_realloc_str( &checked, &maxchecked, checkedlen );
+ (void) strcpy( checked, path );
+ /* Trim trailing slashes. */
+- while ( checked[checkedlen - 1] == '/' )
++ while ( checkedlen && checked[checkedlen - 1] == '/' )
+ {
+ checked[checkedlen - 1] = '\0';
+ --checkedlen;
+@@ -1502,7 +1502,7 @@
+ restlen = strlen( path );
+ httpd_realloc_str( &rest, &maxrest, restlen );
+ (void) strcpy( rest, path );
+- if ( rest[restlen - 1] == '/' )
++ if ( restlen && rest[restlen - 1] == '/' )
+ rest[--restlen] = '\0'; /* trim trailing slash */
+ if ( ! tildemapped )
+ /* Remove any leading slashes. */
+@@ -3889,6 +3889,9 @@
httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl );
return -1;
}
Modified: head/www/thttpd/files/patch-thttpd.c
==============================================================================
--- head/www/thttpd/files/patch-thttpd.c Sun Jan 18 11:40:01 2015 (r377323)
+++ head/www/thttpd/files/patch-thttpd.c Sun Jan 18 12:01:18 2015 (r377324)
@@ -1,6 +1,42 @@
--- thttpd.c.orig Wed Jun 29 19:50:59 2005
+++ thttpd.c Sun Jun 17 21:30:11 2007
-@@ -1723,12 +1723,45 @@
+@@ -331,6 +331,7 @@
+ re_open_logfile( void )
+ {
+ FILE* logfp;
++ int retchmod;
+
+ if ( no_log || hs == (httpd_server*) 0 )
+ return;
+@@ -340,7 +341,8 @@
+ {
+ syslog( LOG_NOTICE, "re-opening logfile" );
+ logfp = fopen( logfile, "a" );
+- if ( logfp == (FILE*) 0 )
++ retchmod = chmod( logfile, S_IRUSR|S_IWUSR );
++ if ( logfp == (FILE*) 0 || retchmod != 0 )
+ {
+ syslog( LOG_CRIT, "re-opening %.80s - %m", logfile );
+ return;
+@@ -360,6 +362,7 @@
+ gid_t gid = 32767;
+ char cwd[MAXPATHLEN+1];
+ FILE* logfp;
++ int retchmod;
+ int num_ready;
+ int cnum;
+ connecttab* c;
+@@ -429,7 +432,8 @@
+ else
+ {
+ logfp = fopen( logfile, "a" );
+- if ( logfp == (FILE*) 0 )
++ retchmod = chmod( logfile, S_IRUSR|S_IWUSR|S_IRGRP );
++ if ( logfp == (FILE*) 0 || retchmod != 0 )
+ {
+ syslog( LOG_CRIT, "%.80s - %m", logfile );
+ perror( logfile );
+@@ -1714,12 +1718,45 @@
if ( hc->responselen == 0 )
{
/* No, just write the file. */
@@ -46,7 +82,7 @@
/* Yes. We'll combine headers and file into a single writev(),
** hoping that this generates a single packet.
*/
-@@ -1739,6 +1772,7 @@
+@@ -1730,6 +1767,7 @@
iv[1].iov_base = &(hc->file_address[c->next_byte_index]);
iv[1].iov_len = MIN( c->end_byte_index - c->next_byte_index, max_bytes );
sz = writev( hc->conn_fd, iv, 2 );
@@ -54,7 +90,7 @@
}
if ( sz < 0 && errno == EINTR )
-@@ -1786,7 +1820,11 @@
+@@ -1777,7 +1815,11 @@
**
** And ECONNRESET isn't interesting either.
*/
More information about the svn-ports-all
mailing list