Cygwin: normalize_win32_path: Avoid buffer underruns
Thanks to Ken Harris <Ken.Harris@mathworks.com> for the diagnosis. When backing up tail to handle a "..", the code only checked that it didn't underrun the destination buffer while removing path components. It did *not* take into account that the first backslash in the path had to be kept intact. Example path to trigger the problem: "C:\A..\..\..\B' Fix this by moving the dst pointer to the first backslash so subsequent tests cannot underrun this position. Also make sure that we always *have* a backslash. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
		
							parent
							
								
									7d00a5e320
								
							
						
					
					
						commit
						35998fc2fa
					
				|  | @ -1336,6 +1336,7 @@ int | ||||||
| normalize_win32_path (const char *src, char *dst, char *&tail) | normalize_win32_path (const char *src, char *dst, char *&tail) | ||||||
| { | { | ||||||
|   const char *src_start = src; |   const char *src_start = src; | ||||||
|  |   const char *dst_start = dst; | ||||||
|   bool beg_src_slash = isdirsep (src[0]); |   bool beg_src_slash = isdirsep (src[0]); | ||||||
| 
 | 
 | ||||||
|   tail = dst; |   tail = dst; | ||||||
|  | @ -1370,27 +1371,43 @@ normalize_win32_path (const char *src, char *dst, char *&tail) | ||||||
| 	      src += 2; | 	      src += 2; | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|  |       dst = tail; | ||||||
|  |       /* If backslash is missing in src, add one. */ | ||||||
|  |       if (!isdirsep (src[0])) | ||||||
|  | 	*tail++ = '\\'; | ||||||
|     } |     } | ||||||
|   if (tail == dst) |   if (tail == dst_start) | ||||||
|     { |     { | ||||||
|       if (isdrive (src)) |       if (isdrive (src)) | ||||||
|  | 	{ | ||||||
| 	  /* Always convert drive letter to uppercase for case sensitivity. */ | 	  /* Always convert drive letter to uppercase for case sensitivity. */ | ||||||
| 	  *tail++ = cyg_toupper (*src++); | 	  *tail++ = cyg_toupper (*src++); | ||||||
|  | 	  *tail++ = *src++; | ||||||
|  | 	  dst = tail; | ||||||
|  | 	  /* If backslash is missing in src, add one. */ | ||||||
|  | 	  if (!isdirsep (src[0])) | ||||||
|  | 	    *tail++ = '\\'; | ||||||
|  | 	} | ||||||
|       else if (*src != '/') |       else if (*src != '/') | ||||||
| 	{ | 	{ | ||||||
| 	  if (beg_src_slash) | 	  if (beg_src_slash) | ||||||
| 	    tail += cygheap->cwd.get_drive (dst); | 	    dst = (tail += cygheap->cwd.get_drive (dst)); | ||||||
| 	  else if (!cygheap->cwd.get (dst, 0)) | 	  else if (cygheap->cwd.get (dst, 0)) | ||||||
| 	    return get_errno (); |  | ||||||
| 	  else |  | ||||||
| 	    { | 	    { | ||||||
| 	      tail = strchr (tail, '\0'); | 	      tail = strchr (tail, '\0'); | ||||||
| 	      if (tail[-1] != '\\') | 	      if (tail[-1] != '\\') | ||||||
| 		*tail++ = '\\'; | 		*tail++ = '\\'; | ||||||
|  | 	      dst = tail - 1; | ||||||
| 	    } | 	    } | ||||||
|  | 	  else | ||||||
|  | 	    return get_errno (); | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |   /* At this point dst points to the first backslash, even if it only gets
 | ||||||
|  |      written in the first iteration of the following loop.  Backing up to | ||||||
|  |      handle ".." components can not underrun that border (thus avoiding | ||||||
|  |      subsequent buffer underruns with fatal results). */ | ||||||
|   while (*src) |   while (*src) | ||||||
|     { |     { | ||||||
|       /* Strip duplicate /'s.  */ |       /* Strip duplicate /'s.  */ | ||||||
|  | @ -1442,7 +1459,7 @@ normalize_win32_path (const char *src, char *dst, char *&tail) | ||||||
|   if (tail > dst + 1 && tail[-1] == '.' && tail[-2] == '\\') |   if (tail > dst + 1 && tail[-1] == '.' && tail[-2] == '\\') | ||||||
|     tail--; |     tail--; | ||||||
|   *tail = '\0'; |   *tail = '\0'; | ||||||
|   debug_printf ("%s = normalize_win32_path (%s)", dst, src_start); |   debug_printf ("%s = normalize_win32_path (%s)", dst_start, src_start); | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue