[114131] trunk/base/src/darwintracelib1.0

cal at macports.org cal at macports.org
Fri Nov 29 16:05:22 PST 2013


Revision: 114131
          https://trac.macports.org/changeset/114131
Author:   cal at macports.org
Date:     2013-11-29 16:05:22 -0800 (Fri, 29 Nov 2013)
Log Message:
-----------
darwintrace: Don't always follow symlinks

Only follow symlinks in __darwintrace_is_in_sandbox() when the DT_FOLLOWSYMS
flag is set. This has the following advantages:
 - lstat(2) and readlink(2) work on symlinks that point to files outside of the
   sandbox (previously, these attempts would have returned ENOENT).
 - readdir(3) is a lot faster again, because it doesn't have to lstat(2) and
   possibly readlink(2) every file in a loop.

Modified Paths:
--------------
    trunk/base/src/darwintracelib1.0/access.c
    trunk/base/src/darwintracelib1.0/darwintrace.c
    trunk/base/src/darwintracelib1.0/darwintrace.h
    trunk/base/src/darwintracelib1.0/mkdir.c
    trunk/base/src/darwintracelib1.0/open.c
    trunk/base/src/darwintracelib1.0/proc.c
    trunk/base/src/darwintracelib1.0/readlink.c
    trunk/base/src/darwintracelib1.0/rename.c
    trunk/base/src/darwintracelib1.0/rmdir.c
    trunk/base/src/darwintracelib1.0/stat.c
    trunk/base/src/darwintracelib1.0/unlink.c

Modified: trunk/base/src/darwintracelib1.0/access.c
===================================================================
--- trunk/base/src/darwintracelib1.0/access.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/access.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -47,7 +47,7 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 		errno = ENOENT;
 		result = -1;
 	} else {

Modified: trunk/base/src/darwintracelib1.0/darwintrace.c
===================================================================
--- trunk/base/src/darwintracelib1.0/darwintrace.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/darwintrace.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -825,6 +825,13 @@
 			}
 		}
 
+		if ((flags & DT_FOLLOWSYMS) == 0) {
+			// only expand symlinks when the DT_FOLLOWSYMS flags is set;
+			// otherwise just ignore whether this path is a symlink or not to
+			// speed up readdir(3).
+			break;
+		}
+
 		if (++loopCount >= 10) {
 			// assume cylce and let the OS deal with that (yes, this actually
 			// happens in software!)

Modified: trunk/base/src/darwintracelib1.0/darwintrace.h
===================================================================
--- trunk/base/src/darwintracelib1.0/darwintrace.h	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/darwintrace.h	2013-11-30 00:05:22 UTC (rev 114131)
@@ -66,8 +66,9 @@
 #endif
 
 enum {
-	DT_REPORT   = 1 << 0,
-	DT_ALLOWDIR = 1 << 1
+	DT_REPORT     = 1 << 0,
+	DT_ALLOWDIR   = 1 << 1,
+	DT_FOLLOWSYMS = 1 << 2
 };
 
 /**
@@ -104,6 +105,12 @@
  *                    path references an existing directory. Set this for
  *                    read operations such as stat(2), omit this for operations
  *                    that modify directories like rmdir(2) and mkdir(2).
+ *                  - DT_FOLLOWSYMS: Check for and expand symlinks, while
+ *                    checking both the link name and the link target against
+ *                    the sandbox. Set this for all operations that read file
+ *                    contents or check file attributes. Omit this flag for
+ *                    operations that only list the file (or rather symlink)
+ *                    name.
  * \return \c true if the file is within sandbox bounds, \c false if access
  *         should be denied
  */

Modified: trunk/base/src/darwintracelib1.0/mkdir.c
===================================================================
--- trunk/base/src/darwintracelib1.0/mkdir.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/mkdir.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -54,7 +54,7 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_FOLLOWSYMS)) {
 		struct stat st;
 		if (-1 == lstat(path, &st) && errno == ENOENT) {
 			// directory doesn't exist yet */

Modified: trunk/base/src/darwintracelib1.0/open.c
===================================================================
--- trunk/base/src/darwintracelib1.0/open.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/open.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -53,7 +53,7 @@
 	__darwintrace_setup();
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 		errno = ((flags & O_CREAT) > 0) ? EACCES : ENOENT;
 		result = -1;
 	} else {

Modified: trunk/base/src/darwintracelib1.0/proc.c
===================================================================
--- trunk/base/src/darwintracelib1.0/proc.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/proc.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -237,7 +237,7 @@
 		}
 
 		/* check the iterpreter against the sandbox */
-		if (!__darwintrace_is_in_sandbox(interp, DT_REPORT | DT_ALLOWDIR)) {
+		if (!__darwintrace_is_in_sandbox(interp, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 			close(fd);
 			return ENOENT;
 		}
@@ -260,7 +260,7 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 		errno = ENOENT;
 		result = -1;
 	} else {
@@ -310,7 +310,7 @@
 	static posix_spawn_t prev_posix_spawn = NULL;
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 		result = ENOENT;
 	} else {
 		int interp_result = check_interpreter(path);

Modified: trunk/base/src/darwintracelib1.0/readlink.c
===================================================================
--- trunk/base/src/darwintracelib1.0/readlink.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/readlink.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -44,10 +44,6 @@
 
 /**
  * Deny \c readlink(2) if the file is not within the sandbox bounds.
- *
- * FIXME Currently also denies reading the link if the link target does not
- * exist. To fix this, add a parameter to __darwintrace_is_in_sandbox that
- * controls whether symlinks should be followed.
  */
 #ifdef READLINK_IS_NOT_P1003_1A
 int readlink(const char *path, char *buf, int bufsiz) {
@@ -59,6 +55,8 @@
 
 	int result = 0;
 
+	// don't follow symlinks here; whether access to the link target is allowed
+	// or not does not matter for reading the symlink
 	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
 		errno = ENOENT;
 		result = -1;

Modified: trunk/base/src/darwintracelib1.0/rename.c
===================================================================
--- trunk/base/src/darwintracelib1.0/rename.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/rename.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -52,10 +52,10 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(from, DT_REPORT)) {
+	if (!__darwintrace_is_in_sandbox(from, DT_REPORT | DT_FOLLOWSYMS)) {
 		errno = ENOENT;
 		result = -1;
-	} else if (!__darwintrace_is_in_sandbox(to, DT_REPORT)) {
+	} else if (!__darwintrace_is_in_sandbox(to, DT_REPORT | DT_FOLLOWSYMS)) {
 		errno = EACCES;
 		result = -1;
 	} else {

Modified: trunk/base/src/darwintracelib1.0/rmdir.c
===================================================================
--- trunk/base/src/darwintracelib1.0/rmdir.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/rmdir.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -52,7 +52,7 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_FOLLOWSYMS)) {
 		errno = ENOENT;
 		result = -1;
 	} else {

Modified: trunk/base/src/darwintracelib1.0/stat.c
===================================================================
--- trunk/base/src/darwintracelib1.0/stat.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/stat.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -53,7 +53,7 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 		errno = ENOENT;
 		result = -1;
 	} else {
@@ -74,7 +74,7 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 		errno = ENOENT;
 		result = -1;
 	} else {
@@ -98,6 +98,7 @@
 
 	int result = 0;
 
+	// don't follow symlinks for lstat
 	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
 		errno = ENOENT;
 		result = -1;
@@ -119,6 +120,7 @@
 
 	int result = 0;
 
+	// don't follow symlinks for lstat
 	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
 		errno = ENOENT;
 		result = -1;

Modified: trunk/base/src/darwintracelib1.0/unlink.c
===================================================================
--- trunk/base/src/darwintracelib1.0/unlink.c	2013-11-29 23:30:23 UTC (rev 114130)
+++ trunk/base/src/darwintracelib1.0/unlink.c	2013-11-30 00:05:22 UTC (rev 114131)
@@ -52,7 +52,7 @@
 
 	int result = 0;
 
-	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
+	if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
 		errno = ENOENT;
 		result = -1;
 	} else {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20131129/b8872675/attachment.html>


More information about the macports-changes mailing list