lkml.org 
[lkml]   [2020]   [May]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: [PATCH 3/5] exec: Remove recursion from search_binary_handler
    Kees Cook <keescook@chromium.org> writes:

    > On Tue, May 12, 2020 at 04:47:14PM -0700, Kees Cook wrote:
    >> And now I wonder if qemu actually uses the resulting AT_EXECFD ...
    >
    > It does, though I'm not sure if this is to support crossing mount points,
    > dropping privileges, or something else, since it does fall back to just
    > trying to open the file.
    >
    > execfd = qemu_getauxval(AT_EXECFD);
    > if (execfd == 0) {
    > execfd = open(filename, O_RDONLY);
    > if (execfd < 0) {
    > printf("Error while loading %s: %s\n", filename, strerror(errno));
    > _exit(EXIT_FAILURE);
    > }
    > }

    My hunch is that the fallback exists from a time when the kernel did not
    implement AT_EXECFD, or so that qemu can run on kernels that don't
    implement AT_EXECFD. It doesn't really matter unless the executable is
    suid, or otherwise changes privileges.


    I looked into this a bit to remind myself why exec works the way it
    works, with changing privileges.

    The classic attack is pointing a symlink at a #! script that is suid or
    otherwise changes privileges. The kernel will open the script and set
    the privileges, read the interpreter from the first line, and proceed to
    exec the interpreter. The interpreter will then open the script using
    the pathname supplied by the kernel. The name of the symlink.
    Before the interpreter reopens the script the attack would replace
    the symlink with a script that does something else, but gets to run
    with the privileges of the script.


    Defending against that time of check vs time of use attack is why
    bprm_fill_uid, and cap_bprm_set_creds use the credentials derived from
    the interpreter instead of the credentials derived from the script.


    The other defense is to replace the pathname of the executable that the
    intepreter will open with /dev/fd/N.

    All of this predates Linux entirely. I do remember this was fixed at
    some point in Linux but I don't remember the details. I can just read
    the solution that was picked in the code.



    All of this makes me wonder how are the LSMs protected against this
    attack.

    Let's see the following LSMS implement brpm_set_creds:
    tomoyo - Abuses bprm_set_creds to call tomoyo_load_policy [ safe ]
    smack - Requires CAP_MAC_ADMIN to smack setxattrs [ vulnerable? ]
    Uses those xattrs in smack_bprm_set_creds
    apparmor - Everything is based on names so the symlink [ safe? ]
    attack won't work as it has the wrong name.
    As long as the trusted names can't be renamed
    apparmor appears good.
    selinux - Appears to let anyone set selinux xattrs [ safe? ]
    Requires permission for a sid transfer
    As the attack appears not to allow anything that
    would not be allowed anyway it looks like selinux
    is safe.

    LSM folks, especially Casey am I reading this correctly? Did I
    correctly infer how your LSMs deal with the time of check to time of use
    attack on the script name?

    Eric

    \
     
     \ /
      Last update: 2020-05-14 17:01    [W:3.781 / U:0.464 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site