[Python-checkins] CVS: python/dist/src/PC getpathp.c,1.21,1.22

Mark Hammond python-dev@python.org
Sat, 7 Oct 2000 04:10:53 -0700


Update of /cvsroot/python/python/dist/src/PC
In directory slayer.i.sourceforge.net:/tmp/cvs-serv30457

Modified Files:
	getpathp.c 
Log Message:
Prevent possible buffer overflow exploits under Windows.  As per (the very quick) patch Patch #101801.

Index: getpathp.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/PC/getpathp.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -r1.21 -r1.22
*** getpathp.c	2000/09/10 09:14:53	1.21
--- getpathp.c	2000/10/07 11:10:50	1.22
***************
*** 99,103 ****
  }
  
! 
  static void
  reduce(char *dir)
--- 99,105 ----
  }
  
! /* assumes 'dir' null terminated in bounds.  Never writes
!    beyond existing terminator.
! */
  static void
  reduce(char *dir)
***************
*** 116,121 ****
  	return stat(filename, &buf) == 0;
  }
- 
  
  static int
  ismodule(char *filename)	/* Is module -- check for .pyc/.pyo too */
--- 118,125 ----
  	return stat(filename, &buf) == 0;
  }
  
+ /* Assumes 'filename' MAXPATHLEN+1 bytes long - 
+    may extend 'filename' by one character.
+ */
  static int
  ismodule(char *filename)	/* Is module -- check for .pyc/.pyo too */
***************
*** 132,137 ****
  	return 0;
  }
- 
  
  static void
  join(char *buffer, char *stuff)
--- 136,141 ----
  	return 0;
  }
  
+ /* guarantees buffer will never overflow MAXPATHLEN+1 bytes */
  static void
  join(char *buffer, char *stuff)
***************
*** 152,156 ****
  }
  
! 
  static int
  gotlandmark(char *landmark)
--- 156,163 ----
  }
  
! /* gotlandmark only called by search_for_prefix, which ensures
!    'prefix' is null terminated in bounds.  join() ensures
!    'landmark' can not overflow prefix if too long.
! */
  static int
  gotlandmark(char *landmark)
***************
*** 165,169 ****
  }
  
! 
  static int
  search_for_prefix(char *argv0_path, char *landmark)
--- 172,177 ----
  }
  
! /* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd. 
!    assumption provided by only caller, calculate_path() */
  static int
  search_for_prefix(char *argv0_path, char *landmark)
***************
*** 341,349 ****
  #ifdef UNICODE
  	WCHAR wprogpath[MAXPATHLEN+1];
  	if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
! 		WideCharToMultiByte(CP_ACP, 0, wprogpath, -1, progpath, MAXPATHLEN+1, NULL, NULL);
  		return;
  	}
  #else
  	if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
  		return;
--- 349,366 ----
  #ifdef UNICODE
  	WCHAR wprogpath[MAXPATHLEN+1];
+ 	/* Windows documents that GetModuleFileName() will "truncate",
+ 	   but makes no mention of the null terminator.  Play it safe.
+ 	   PLUS Windows itself defines MAX_PATH as the same, but anyway...
+ 	*/
+ 	wprogpath[MAXPATHLEN]=_T('\0')';
  	if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
! 		WideCharToMultiByte(CP_ACP, 0, 
! 		                    wprogpath, -1, 
! 		                    progpath, MAXPATHLEN+1, 
! 		                    NULL, NULL);
  		return;
  	}
  #else
+ 	/* static init of progpath ensures final char remains \0 */
  	if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
  		return;
***************
*** 363,367 ****
  	if (strchr(prog, SEP))
  #endif
! 		strcpy(progpath, prog);
  	else if (path) {
  		while (1) {
--- 380,384 ----
  	if (strchr(prog, SEP))
  #endif
! 		strncpy(progpath, prog, MAXPATHLEN);
  	else if (path) {
  		while (1) {
***************
*** 370,379 ****
  			if (delim) {
  				size_t len = delim - path;
  				strncpy(progpath, path, len);
  				*(progpath + len) = '\0';
  			}
  			else
! 				strcpy(progpath, path);
  
  			join(progpath, prog);
  			if (exists(progpath))
--- 387,399 ----
  			if (delim) {
  				size_t len = delim - path;
+ 				/* ensure we can't overwrite buffer */
+ 				len = min(MAXPATHLEN,len);
  				strncpy(progpath, path, len);
  				*(progpath + len) = '\0';
  			}
  			else
! 				strncpy(progpath, path, MAXPATHLEN);
  
+ 			/* join() is safe for MAXPATHLEN+1 size buffer */
  			join(progpath, prog);
  			if (exists(progpath))
***************
*** 407,410 ****
--- 427,431 ----
  
  	get_progpath();
+ 	/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
  	strcpy(argv0_path, progpath);
  	reduce(argv0_path);
***************
*** 416,420 ****
  	}
  	else
! 		strcpy(prefix, pythonhome);
  
  	if (envpath && *envpath == '\0')
--- 437,441 ----
  	}
  	else
! 		strncpy(prefix, pythonhome, MAXPATHLEN);
  
  	if (envpath && *envpath == '\0')