httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b..@hyperreal.org
Subject cvs commit: apache-1.3/src/os/win32 util_win32.c
Date Sat, 27 Jun 1998 17:24:13 GMT
ben         98/06/27 10:24:12

  Modified:    src      CHANGES
               src/os/win32 util_win32.c
  Log:
  Eliminate problems with mutiple and trailing slashes. Also deal with trailing .s.
  
  Revision  Changes    Path
  1.934     +7 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.933
  retrieving revision 1.934
  diff -u -r1.933 -r1.934
  --- CHANGES	1998/06/25 21:06:01	1.933
  +++ CHANGES	1998/06/27 17:24:06	1.934
  @@ -1,5 +1,12 @@
   Changes with Apache 1.3.1
   
  +  *) Win32: Don't collapse multiple slashes in PATH_INFO.
  +     [Ben Laurie, Bill Stoddard <wgstodda@us.ibm.com>] PR#2274
  +
  +  *) Win32 (security): Eliminate trailing "."s in path components. These are
  +     ignored by the Windows filesystem, and so can be used to bypass security.
  +	 [Ben Laurie, Alexei Kosut].
  +
     *) We now attempt to dump core when we get SIGILL. [Jim Jagielski]
   
     *) PORT: remove broken test for MAP_FILE in http_main.c.
  
  
  
  1.18      +36 -19    apache-1.3/src/os/win32/util_win32.c
  
  Index: util_win32.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/os/win32/util_win32.c,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- util_win32.c	1998/06/23 19:53:31	1.17
  +++ util_win32.c	1998/06/27 17:24:11	1.18
  @@ -4,14 +4,21 @@
   
   #include "httpd.h"
   
  -static void sub_canonical_filename(char *szCanon, unsigned nCanon, const char *szFile)
  +/* Returns TRUE if the path is real, FALSE if it is PATH_INFO */
  +static BOOL sub_canonical_filename(char *szCanon, unsigned nCanon, const char *szFile)
   {
       char buf[HUGE_STRING_LEN];
       int n;
       char *szFilePart;
  +    char *s;
  +    int nSlashes;
       WIN32_FIND_DATA d;
       HANDLE h;
   
  +    s=strrchr(szFile,'\\');
  +    for(nSlashes=0 ; s > szFile && s[-1] == '\\' ; ++nSlashes,--s)
  +	;
  +
       n = GetFullPathName(szFile, sizeof buf, buf, &szFilePart);
       ap_assert(n);
       ap_assert(n < sizeof buf);
  @@ -68,13 +75,17 @@
           szCanon[3] = '\0';
       }
       if (h == INVALID_HANDLE_VALUE) {
  -	ap_assert(strlen(szCanon)+strlen(szFilePart) < nCanon);
  +	ap_assert(strlen(szCanon)+strlen(szFilePart)+nSlashes < nCanon);
  +	for(n=0 ; n < nSlashes ; ++n)
  +	    strcat(szCanon, "/");
           strcat(szCanon, szFilePart);
  +	return FALSE;
       }
       else {
   	ap_assert(strlen(szCanon)+strlen(d.cFileName) < nCanon);
           strlwr(d.cFileName);
           strcat(szCanon, d.cFileName);
  +	return TRUE;
       }
   }
   
  @@ -86,35 +97,41 @@
   {
       char buf[HUGE_STRING_LEN];
       char b2[HUGE_STRING_LEN];
  -    char *s,*d;
  +    const char *s;
  +    char *d;
  +    int nSlashes;
   
       ap_assert(strlen(szFile) < sizeof b2);
  -    strcpy(b2,szFile);
  -    for(s=b2 ; *s ; ++s)
  -	if(*s == '/')
  -	    *s='\\';
   
       /* Eliminate directories consisting of three or more dots.
          These act like ".." but are not detected by other machinery.
  +       Also get rid of trailing .s on any path component, which are ignored by the filesystem.
  +       Simultaneously, rewrite / to \.
          This is a bit of a kludge - Ben.
       */
  -    for(d=s=b2 ; (*d=*s) ; ++d,++s)
  -	if(!strncmp(s,"\\...",3))
  -	    {
  -	    int n=strspn(s+1,".");
  -	    if(s[n+1] != '\\')
  -		continue;
  -	    s+=n;
  -	    --d;
  +    for(s=szFile,d=b2 ; (*d=*s) ; ++d,++s) {
  +	if(*s == '/')
  +	    *d='\\';
  +	if(*s == '.' && (s[1] == '/' || s[1] == '\\' || !s[1])) {
  +	    while(*d == '.')
  +		--d;
  +	    if(*d == '\\')
  +		--d;
   	    }
  +	}
  +    // Finally, a trailing slash(es) screws thing, so blow them away
  +    for(nSlashes=0 ; d > b2 && d[-1] == '\\' ; --d,++nSlashes)
  +	;
  +    *d='\0';
  +
  +    if(sub_canonical_filename(buf, sizeof buf, b2) && nSlashes)
  +	nSlashes=1;
   
  -    sub_canonical_filename(buf, sizeof buf, b2);
       buf[0]=tolower(buf[0]);
   
  -    if (*szFile && szFile[strlen(szFile)-1] == '/' && buf[strlen(buf)-1]
!= '/') {
  -	ap_assert(strlen(buf)+1 < sizeof buf);
  +    ap_assert(strlen(buf)+nSlashes < sizeof buf);
  +    while(nSlashes--)
           strcat(buf, "/");
  -    }
   
       return ap_pstrdup(pPool, buf);
   }
  
  
  

Mime
View raw message