Changeset 114131


Ignore:
Timestamp:
Nov 30, 2013, 12:05:22 AM (7 years ago)
Author:
cal@…
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.
Location:
trunk/base/src/darwintracelib1.0
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/src/darwintracelib1.0/access.c

    r113026 r114131  
    4848        int result = 0;
    4949
    50         if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
     50        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    5151                errno = ENOENT;
    5252                result = -1;
  • trunk/base/src/darwintracelib1.0/darwintrace.c

    r114096 r114131  
    826826                }
    827827
     828                if ((flags & DT_FOLLOWSYMS) == 0) {
     829                        // only expand symlinks when the DT_FOLLOWSYMS flags is set;
     830                        // otherwise just ignore whether this path is a symlink or not to
     831                        // speed up readdir(3).
     832                        break;
     833                }
     834
    828835                if (++loopCount >= 10) {
    829836                        // assume cylce and let the OS deal with that (yes, this actually
  • trunk/base/src/darwintracelib1.0/darwintrace.h

    r114095 r114131  
    6767
    6868enum {
    69         DT_REPORT   = 1 << 0,
    70         DT_ALLOWDIR = 1 << 1
     69        DT_REPORT     = 1 << 0,
     70        DT_ALLOWDIR   = 1 << 1,
     71        DT_FOLLOWSYMS = 1 << 2
    7172};
    7273
     
    105106 *                    read operations such as stat(2), omit this for operations
    106107 *                    that modify directories like rmdir(2) and mkdir(2).
     108 *                  - DT_FOLLOWSYMS: Check for and expand symlinks, while
     109 *                    checking both the link name and the link target against
     110 *                    the sandbox. Set this for all operations that read file
     111 *                    contents or check file attributes. Omit this flag for
     112 *                    operations that only list the file (or rather symlink)
     113 *                    name.
    107114 * \return \c true if the file is within sandbox bounds, \c false if access
    108115 *         should be denied
  • trunk/base/src/darwintracelib1.0/mkdir.c

    r113026 r114131  
    5555        int result = 0;
    5656
    57         if (!__darwintrace_is_in_sandbox(path, DT_REPORT)) {
     57        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_FOLLOWSYMS)) {
    5858                struct stat st;
    5959                if (-1 == lstat(path, &st) && errno == ENOENT) {
  • trunk/base/src/darwintracelib1.0/open.c

    r113026 r114131  
    5454        int result = 0;
    5555
    56         if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
     56        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    5757                errno = ((flags & O_CREAT) > 0) ? EACCES : ENOENT;
    5858                result = -1;
  • trunk/base/src/darwintracelib1.0/proc.c

    r113823 r114131  
    238238
    239239                /* check the iterpreter against the sandbox */
    240                 if (!__darwintrace_is_in_sandbox(interp, DT_REPORT | DT_ALLOWDIR)) {
     240                if (!__darwintrace_is_in_sandbox(interp, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    241241                        close(fd);
    242242                        return ENOENT;
     
    261261        int result = 0;
    262262
    263         if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
     263        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    264264                errno = ENOENT;
    265265                result = -1;
     
    311311        int result = 0;
    312312
    313         if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
     313        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    314314                result = ENOENT;
    315315        } else {
  • trunk/base/src/darwintracelib1.0/readlink.c

    r113026 r114131  
    4545/**
    4646 * Deny \c readlink(2) if the file is not within the sandbox bounds.
    47  *
    48  * FIXME Currently also denies reading the link if the link target does not
    49  * exist. To fix this, add a parameter to __darwintrace_is_in_sandbox that
    50  * controls whether symlinks should be followed.
    5147 */
    5248#ifdef READLINK_IS_NOT_P1003_1A
     
    6056        int result = 0;
    6157
     58        // don't follow symlinks here; whether access to the link target is allowed
     59        // or not does not matter for reading the symlink
    6260        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
    6361                errno = ENOENT;
  • trunk/base/src/darwintracelib1.0/rename.c

    r113026 r114131  
    5353        int result = 0;
    5454
    55         if (!__darwintrace_is_in_sandbox(from, DT_REPORT)) {
     55        if (!__darwintrace_is_in_sandbox(from, DT_REPORT | DT_FOLLOWSYMS)) {
    5656                errno = ENOENT;
    5757                result = -1;
    58         } else if (!__darwintrace_is_in_sandbox(to, DT_REPORT)) {
     58        } else if (!__darwintrace_is_in_sandbox(to, DT_REPORT | DT_FOLLOWSYMS)) {
    5959                errno = EACCES;
    6060                result = -1;
  • trunk/base/src/darwintracelib1.0/rmdir.c

    r113026 r114131  
    5353        int result = 0;
    5454
    55         if (!__darwintrace_is_in_sandbox(path, DT_REPORT)) {
     55        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_FOLLOWSYMS)) {
    5656                errno = ENOENT;
    5757                result = -1;
  • trunk/base/src/darwintracelib1.0/stat.c

    r113875 r114131  
    5454        int result = 0;
    5555
    56         if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
     56        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    5757                errno = ENOENT;
    5858                result = -1;
     
    7575        int result = 0;
    7676
    77         if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
     77        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    7878                errno = ENOENT;
    7979                result = -1;
     
    9999        int result = 0;
    100100
     101        // don't follow symlinks for lstat
    101102        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
    102103                errno = ENOENT;
     
    120121        int result = 0;
    121122
     123        // don't follow symlinks for lstat
    122124        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
    123125                errno = ENOENT;
  • trunk/base/src/darwintracelib1.0/unlink.c

    r113026 r114131  
    5353        int result = 0;
    5454
    55         if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR)) {
     55        if (!__darwintrace_is_in_sandbox(path, DT_REPORT | DT_ALLOWDIR | DT_FOLLOWSYMS)) {
    5656                errno = ENOENT;
    5757                result = -1;
Note: See TracChangeset for help on using the changeset viewer.