[127673] trunk/base/src/darwintracelib1.0/darwintrace.c
cal at macports.org
cal at macports.org
Fri Oct 31 18:16:19 PDT 2014
Revision: 127673
https://trac.macports.org/changeset/127673
Author: cal at macports.org
Date: 2014-10-31 18:16:19 -0700 (Fri, 31 Oct 2014)
Log Message:
-----------
base: trace mode: deal with resource forks, add error checks, use getattrlist(2) over getcwd(3), closes #44240
- Strip resource forks, fixes #44240.
- Add error checking to deal with buffer overflows due to very long paths in
darwintrace.dylib.
- Remove useless call to strlen("filemap\t") to save the runtime cost.
Modified Paths:
--------------
trunk/base/src/darwintracelib1.0/darwintrace.c
Modified: trunk/base/src/darwintracelib1.0/darwintrace.c
===================================================================
--- trunk/base/src/darwintracelib1.0/darwintrace.c 2014-11-01 00:41:11 UTC (rev 127672)
+++ trunk/base/src/darwintracelib1.0/darwintrace.c 2014-11-01 01:16:19 UTC (rev 127673)
@@ -44,6 +44,7 @@
#endif
#include <errno.h>
+#include <inttypes.h>
#include <pthread.h>
#include <string.h>
#include <sys/attr.h>
@@ -309,7 +310,7 @@
free(newfilemap);
if (filemap != NULL)
break;
- newfilemap = __send("filemap\t", (uint32_t) strlen("filemap\t"), 1);
+ newfilemap = __send("filemap\t", 8, 1);
} while (!CAS(NULL, newfilemap, &filemap));
#if DARWINTRACE_DEBUG && 0
@@ -422,7 +423,11 @@
char logbuffer[BUFFER_SIZE];
size = snprintf(logbuffer, sizeof(logbuffer), "%s\t%s", op, path);
- __send(logbuffer, size, 0);
+ // Check if the buffer was short. If it was, discard the message silently,
+ // assuming it isn't important enough to error out.
+ if (size < BUFFER_SIZE) {
+ __send(logbuffer, size, 0);
+ }
}
/**
@@ -452,7 +457,8 @@
}
len = snprintf(buffer, sizeof(buffer), "dep_check\t%s", path);
- if (len > sizeof(buffer)) {
+ if (len >= sizeof(buffer)) {
+ fprintf(stderr, "darwintrace: truncating buffer length from %" PRIu32 " to %zu.", len, sizeof(buffer) - 1);
len = sizeof(buffer) - 1;
}
p = __send(buffer, len, 1);
@@ -660,6 +666,7 @@
bool __darwintrace_is_in_sandbox(const char *path, int flags) {
#define lstat(x, y) syscall(LSTATSYSNUM, (x), (y))
#define readlink(x,y,z) syscall(SYS_readlink, (x), (y), (z))
+#define getattrlist(v,w,x,y,z) syscall(SYS_getattrlist, (v), (w), (x), (y), (z))
if (!filemap) {
return true;
}
@@ -686,12 +693,42 @@
const char *token = NULL;
size_t idx;
if (*path != '/') {
- // The path isn't absolute, start by populating pathcomponents with the
- // current working directory
+ /*
+ * The path isn't absolute, start by populating pathcomponents with the
+ * current working directory.
+ *
+ * However, we avoid getcwd(3) if we can and use getattrlist(2) with
+ * ATTR_CMN_FULLPATH instead, because getcwd(3) will open all parent
+ * directories, read them, search for the current component using its
+ * inode obtained from lstat(., .., ../.., etc.) and build the path
+ * this way, which is inefficient and will also call back into
+ * darwintrace code.
+ */
+# ifdef ATTR_CMN_FULLPATH
+ struct attrlist attrlist;
+ attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
+ attrlist.reserved = 0;
+ attrlist.commonattr = ATTR_CMN_FULLPATH;
+ attrlist.volattr = 0;
+ attrlist.dirattr = 0;
+ attrlist.fileattr = 0;
+ attrlist.forkattr = 0;
+
+ char attrbuf[sizeof(uint32_t) + sizeof(attrreference_t) + (PATH_MAX + 1)];
+ /* attrlength attrref_t for the name UTF-8 name up to PATH_MAX chars */
+
+ if (-1 == (getattrlist(".", &attrlist, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW))) {
+ perror("darwintrace: getattrlist");
+ abort();
+ }
+ attrreference_t *nameAttrRef = (attrreference_t *) (attrbuf + sizeof(uint32_t));
+ strlcpy(normPath, ((char *) nameAttrRef) + nameAttrRef->attr_dataoffset, sizeof(normPath));
+# else /* defined(ATTR_CMN_FULLPATH) */
if (getcwd(normPath, sizeof(normPath)) == NULL) {
perror("darwintrace: getcwd");
abort();
}
+# endif /* defined(ATTR_CMN_FULLPATH) */
char *writableToken = normPath + 1;
while ((idx = strcspn(writableToken, "/")) > 0) {
@@ -768,6 +805,13 @@
token += idx + 1;
}
+ // strip off resource forks
+ if (numComponents >= 2 &&
+ strcmp("..namedfork", pathComponents[numComponents - 2].start) == 0 &&
+ strcmp("rsrc", pathComponents[numComponents - 1].start) == 0) {
+ numComponents -= 2;
+ }
+
# ifdef ATTR_CMN_FULLPATH
if (numComponents >= 3 && strncmp(".vol", pathComponents[0].start, pathComponents[0].len) == 0) {
// path in VOLFS, try to get inode -> name lookup from getattrlist(2).
@@ -930,6 +974,7 @@
} while (pathIsSymlink);
return __darwintrace_sandbox_check(normPath, flags);
+#undef getattrlist
#undef readlink
#undef lstat
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20141031/ed95c8d7/attachment-0001.html>
More information about the macports-changes
mailing list