Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Apr 2014 19:48:29 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r264417 - head/lib/libc/stdlib
Message-ID:  <201404131948.s3DJmTbW007793@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Sun Apr 13 19:48:28 2014
New Revision: 264417
URL: http://svnweb.freebsd.org/changeset/base/264417

Log:
  realpath(): Properly fail "." or ".." components after non-directories.
  
  If realpath() is called on pathnames like "/dev/null/." or "/dev/null/..",
  it should fail with [ENOTDIR]. Pathnames like "/dev/null/" already failed as
  they should.
  
  Also, put the check for non-directories after lstatting the previous
  component instead of when the empty component (consecutive or trailing
  slashes) is detected, saving an lstat() call and some lines of code.
  
  PR:		kern/82980
  MFC after:	2 weeks

Modified:
  head/lib/libc/stdlib/realpath.c

Modified: head/lib/libc/stdlib/realpath.c
==============================================================================
--- head/lib/libc/stdlib/realpath.c	Sun Apr 13 18:51:39 2014	(r264416)
+++ head/lib/libc/stdlib/realpath.c	Sun Apr 13 19:48:28 2014	(r264417)
@@ -132,26 +132,7 @@ realpath(const char * __restrict path, c
 			resolved[resolved_len] = '\0';
 		}
 		if (next_token[0] == '\0') {
-			/*
-			 * Handle consequential slashes.  The path
-			 * before slash shall point to a directory.
-			 *
-			 * Only the trailing slashes are not covered
-			 * by other checks in the loop, but we verify
-			 * the prefix for any (rare) "//" or "/\0"
-			 * occurrence to not implement lookahead.
-			 */
-			if (lstat(resolved, &sb) != 0) {
-				if (m)
-					free(resolved);
-				return (NULL);
-			}
-			if (!S_ISDIR(sb.st_mode)) {
-				if (m)
-					free(resolved);
-				errno = ENOTDIR;
-				return (NULL);
-			}
+			/* Handle consequential slashes. */
 			continue;
 		}
 		else if (strcmp(next_token, ".") == 0)
@@ -236,6 +217,11 @@ realpath(const char * __restrict path, c
 				}
 			}
 			left_len = strlcpy(left, symlink, sizeof(left));
+		} else if (!S_ISDIR(sb.st_mode) && p != NULL) {
+			if (m)
+				free(resolved);
+			errno = ENOTDIR;
+			return (NULL);
 		}
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404131948.s3DJmTbW007793>