Skip to content
  • Kees Cook's avatar
    fs: add link restrictions · 800179c9
    Kees Cook authored
    This adds symlink and hardlink restrictions to the Linux VFS.
    
    Symlinks:
    
    A long-standing class of security issues is the symlink-based
    time-of-check-time-of-use race, most commonly seen in world-writable
    directories like /tmp. The common method of exploitation of this flaw
    is to cross privilege boundaries when following a given symlink (i.e. a
    root process follows a symlink belonging to another user). For a likely
    incomplete list of hundreds of examples across the years, please see:
    http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
    
    The solution is to permit symlinks to only be followed when outside
    a sticky world-writable directory, or when the uid of the symlink and
    follower match, or when the directory owner matches the symlink's owner.
    
    Some pointers to the history of earlier discussion that I could find:
    
     1996 Aug, Zygo Blaxell
      http://marc.info/?l=bugtraq&m=87602167419830&w=2
     1996 Oct, Andrew Tridgell
      http://lkml.indiana.edu/hypermail/linux/kernel/9610.2/0086.html
     1997 Dec, Albert D Cahalan
      http://lkml.org/lkml/1997/12/16/4
     2005 Feb, Lorenzo Hernández García-Hierro
      http://lkml.indiana.edu/hypermail/linux/kernel/0502.0/1896.html
     2010 May, Kees Cook
      https://lkml.org/lkml/2010/5/30/144
    
    Past objections and rebuttals could be summarized as:
    
     - Violates POSIX.
       - POSIX didn't consider this situation and it's not useful to follow
         a broken specification at the cost of security.
     - Might break unknown applications that use this feature.
       - Applications that break because of the change are easy to spot and
         fix. Applications that are vulnerable to symlink ToCToU by not having
         the change aren't. Additionally, no applications have yet been found
         that rely on this behavior.
     - Applications should just use mkstemp() or O_CREATE|O_EXCL.
       - True, but applications are not perfect, and new software is written
         all the time that makes these mistakes; blocking this flaw at the
         kernel is a single solution to the entire class of vulnerability.
     - This should live in the core VFS.
       - This should live in an LSM. (https://lkml.org/lkml/2010/5/31/135)
     - This should live in an LSM.
       - This should live in the core VFS. (https://lkml.org/lkml/2010/8/2/188)
    
    Hardlinks:
    
    On systems that have user-writable directories on the same partition
    as system files, a long-standing class of security issues is the
    hardlink-based time-of-check-time-of-use race, most commonly seen in
    world-writable directories like /tmp. The common method of exploitation
    of this flaw is to cross privilege boundaries when following a given
    hardlink (i.e. a root process follows a hardlink created by another
    user). Additionally, an issue exists where users can "pin" a potentially
    vulnerable setuid/setgid file so that an administrator will not actually
    upgrade a system fully.
    
    The solution is to permit hardlinks to only be created when the user is
    already the existing file's owner, or if they already have read/write
    access to the existing file.
    
    Many Linux users are surprised when they learn they can link to files
    they have no access to, so this change appears to follow the doctrine
    of "least surprise". Additionally, this change does not violate POSIX,
    which states "the implementation may require that the calling process
    has permission to access the existing file"[1].
    
    This change is known to break some implementations of the "at" daemon,
    though the version used by Fedora and Ubuntu has been fixed[2] for
    a while. Otherwise, the change has been undisruptive while in use in
    Ubuntu for the last 1.5 years.
    
    [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html
    [2] http://anonscm.debian.org/gitweb/?p=collab-maint/at.git;a=commitdiff;h=f4114656c3a6c6f6070e315ffdf940a49eda3279
    
    
    
    This patch is based on the patches in Openwall and grsecurity, along with
    suggestions from Al Viro. I have added a sysctl to enable the protected
    behavior, and documentation.
    
    Signed-off-by: default avatarKees Cook <keescook@chromium.org>
    Acked-by: default avatarIngo Molnar <mingo@elte.hu>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    800179c9