1. 02 8月, 2017 10 次提交
    • K
      exec: Consolidate pdeath_signal clearing · fe8993b3
      Kees Cook 提交于
      Instead of an additional secureexec check for pdeath_signal, just move it
      up into the initial secureexec test. Neither perf nor arch code touches
      pdeath_signal, so the relocation shouldn't change anything.
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      fe8993b3
    • K
      exec: Use sane stack rlimit under secureexec · 64701dee
      Kees Cook 提交于
      For a secureexec, before memory layout selection has happened, reset the
      stack rlimit to something sane to avoid the caller having control over
      the resulting layouts.
      
      $ ulimit -s
      8192
      $ ulimit -s unlimited
      $ /bin/sh -c 'ulimit -s'
      unlimited
      $ sudo /bin/sh -c 'ulimit -s'
      8192
      
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Reviewed-by: NJames Morris <james.l.morris@oracle.com>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      64701dee
    • K
      exec: Consolidate dumpability logic · 473d8963
      Kees Cook 提交于
      Since it's already valid to set dumpability in the early part of
      setup_new_exec(), we can consolidate the logic into a single place.
      The BINPRM_FLAGS_ENFORCE_NONDUMP is set during would_dump() calls
      before setup_new_exec(), so its test is safe to move as well.
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      Reviewed-by: NJames Morris <james.l.morris@oracle.com>
      473d8963
    • K
      exec: Use secureexec for clearing pdeath_signal · a70423df
      Kees Cook 提交于
      Like dumpability, clearing pdeath_signal happens both in setup_new_exec()
      and later in commit_creds(). The test in setup_new_exec() is different
      from all other privilege comparisons, though: it is checking the new cred
      (bprm) uid vs the old cred (current) euid. This appears to be a bug,
      introduced by commit a6f76f23 ("CRED: Make execve() take advantage of
      copy-on-write credentials"):
      
      -       if (bprm->e_uid != current_euid() ||
      -           bprm->e_gid != current_egid()) {
      -               set_dumpable(current->mm, suid_dumpable);
      +       if (bprm->cred->uid != current_euid() ||
      +           bprm->cred->gid != current_egid()) {
      
      It was bprm euid vs current euid (and egids), but the effective got
      dropped. Nothing in the exec flow changes bprm->cred->uid (nor gid).
      The call traces are:
      
      	prepare_bprm_creds()
      	    prepare_exec_creds()
      	        prepare_creds()
      	            memcpy(new_creds, old_creds, ...)
      	            security_prepare_creds() (unimplemented by commoncap)
      	...
      	prepare_binprm()
      	    bprm_fill_uid()
      	        resets euid/egid to current euid/egid
      	        sets euid/egid on bprm based on set*id file bits
      	    security_bprm_set_creds()
      		cap_bprm_set_creds()
      		        handle all caps-based manipulations
      
      so this test is effectively a test of current_uid() vs current_euid(),
      which is wrong, just like the prior dumpability tests were wrong.
      
      The commit log says "Clear pdeath_signal and set dumpable on
      certain circumstances that may not be covered by commit_creds()." This
      may be meaning the earlier old euid vs new euid (and egid) test that
      got changed.
      
      Luckily, as with dumpability, this is all masked by commit_creds()
      which performs old/new euid and egid tests and clears pdeath_signal.
      
      And again, like dumpability, we should include LSM secureexec logic for
      pdeath_signal clearing. For example, Smack goes out of its way to clear
      pdeath_signal when it finds a secureexec condition.
      
      Cc: David Howells <dhowells@redhat.com>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      Reviewed-by: NJames Morris <james.l.morris@oracle.com>
      a70423df
    • K
      exec: Use secureexec for setting dumpability · e37fdb78
      Kees Cook 提交于
      The examination of "current" to decide dumpability is wrong. This was a
      check of and euid/uid (or egid/gid) mismatch in the existing process,
      not the newly created one. This appears to stretch back into even the
      "history.git" tree. Luckily, dumpability is later set in commit_creds().
      In earlier kernel versions before creds existed, similar checks also
      existed late in the exec flow, covering up the mistake as far back as I
      could find.
      
      Note that because the commit_creds() check examines differences of euid,
      uid, egid, gid, and capabilities between the old and new creds, it would
      look like the setup_new_exec() dumpability test could be entirely removed.
      However, the secureexec test may cover a different set of tests (specific
      to the LSMs) than what commit_creds() checks for. So, fix this test to
      use secureexec (the removed euid tests are redundant to the commoncap
      secureexec checks now).
      
      Cc: David Howells <dhowells@redhat.com>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      Reviewed-by: NJames Morris <james.l.morris@oracle.com>
      e37fdb78
    • K
      LSM: drop bprm_secureexec hook · 2af62280
      Kees Cook 提交于
      This removes the bprm_secureexec hook since the logic has been folded into
      the bprm_set_creds hook for all LSMs now.
      
      Cc: Eric W. Biederman <ebiederm@xmission.com>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Reviewed-by: NJohn Johansen <john.johansen@canonical.com>
      Acked-by: NJames Morris <james.l.morris@oracle.com>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      2af62280
    • K
      commoncap: Refactor to remove bprm_secureexec hook · 46d98eb4
      Kees Cook 提交于
      The commoncap implementation of the bprm_secureexec hook is the only LSM
      that depends on the final call to its bprm_set_creds hook (since it may
      be called for multiple files, it ignores bprm->called_set_creds). As a
      result, it cannot safely _clear_ bprm->secureexec since other LSMs may
      have set it.  Instead, remove the bprm_secureexec hook by introducing a
      new flag to bprm specific to commoncap: cap_elevated. This is similar to
      cap_effective, but that is used for a specific subset of elevated
      privileges, and exists solely to track state from bprm_set_creds to
      bprm_secureexec. As such, it will be removed in the next patch.
      
      Here, set the new bprm->cap_elevated flag when setuid/setgid has happened
      from bprm_fill_uid() or fscapabilities have been prepared. This temporarily
      moves the bprm_secureexec hook to a static inline. The helper will be
      removed in the next patch; this makes the step easier to review and bisect,
      since this does not introduce any changes to inputs nor outputs to the
      "elevated privileges" calculation.
      
      The new flag is merged with the bprm->secureexec flag in setup_new_exec()
      since this marks the end of any further prepare_binprm() calls.
      
      Cc: Andy Lutomirski <luto@kernel.org>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Reviewed-by: NAndy Lutomirski <luto@kernel.org>
      Acked-by: NJames Morris <james.l.morris@oracle.com>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      46d98eb4
    • K
      binfmt: Introduce secureexec flag · c425e189
      Kees Cook 提交于
      The bprm_secureexec hook can be moved earlier. Right now, it is called
      during create_elf_tables(), via load_binary(), via search_binary_handler(),
      via exec_binprm(). Nearly all (see exception below) state used by
      bprm_secureexec is created during the bprm_set_creds hook, called from
      prepare_binprm().
      
      For all LSMs (except commoncaps described next), only the first execution
      of bprm_set_creds takes any effect (they all check bprm->called_set_creds
      which prepare_binprm() sets after the first call to the bprm_set_creds
      hook).  However, all these LSMs also only do anything with bprm_secureexec
      when they detected a secure state during their first run of bprm_set_creds.
      Therefore, it is functionally identical to move the detection into
      bprm_set_creds, since the results from secureexec here only need to be
      based on the first call to the LSM's bprm_set_creds hook.
      
      The single exception is that the commoncaps secureexec hook also examines
      euid/uid and egid/gid differences which are controlled by bprm_fill_uid(),
      via prepare_binprm(), which can be called multiple times (e.g.
      binfmt_script, binfmt_misc), and may clear the euid/egid for the final
      load (i.e. the script interpreter). However, while commoncaps specifically
      ignores bprm->cred_prepared, and runs its bprm_set_creds hook each time
      prepare_binprm() may get called, it needs to base the secureexec decision
      on the final call to bprm_set_creds. As a result, it will need special
      handling.
      
      To begin this refactoring, this adds the secureexec flag to the bprm
      struct, and calls the secureexec hook during setup_new_exec(). This is
      safe since all the cred work is finished (and past the point of no return).
      This explicit call will be removed in later patches once the hook has been
      removed.
      
      Cc: David Howells <dhowells@redhat.com>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Reviewed-by: NJohn Johansen <john.johansen@canonical.com>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      Reviewed-by: NJames Morris <james.l.morris@oracle.com>
      c425e189
    • K
      exec: Correct comments about "point of no return" · a9208e42
      Kees Cook 提交于
      In commit 221af7f8 ("Split 'flush_old_exec' into two functions"),
      the comment about the point of no return should have stayed in
      flush_old_exec() since it refers to "bprm->mm = NULL;" line, but prior
      changes in commits c89681ed ("remove steal_locks()"), and
      fd8328be ("sanitize handling of shared descriptor tables in failing
      execve()") made it look like it meant the current->sas_ss_sp line instead.
      
      The comment was referring to the fact that once bprm->mm is NULL, all
      failures from a binfmt load_binary hook (e.g. load_elf_binary), will
      get SEGV raised against current. Move this comment and expand the
      explanation a bit, putting it above the assignment this time, and add
      details about the true nature of "point of no return" being the call
      to flush_old_exec() itself.
      
      This also removes an erroneous commet about when credentials are being
      installed. That has its own dedicated function, install_exec_creds(),
      which carries a similar (and correct) comment, so remove the bogus comment
      where installation is not actually happening.
      
      Cc: David Howells <dhowells@redhat.com>
      Cc: Eric W. Biederman <ebiederm@xmission.com>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Acked-by: N"Eric W. Biederman" <ebiederm@xmission.com>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      a9208e42
    • K
      exec: Rename bprm->cred_prepared to called_set_creds · ddb4a144
      Kees Cook 提交于
      The cred_prepared bprm flag has a misleading name. It has nothing to do
      with the bprm_prepare_cred hook, and actually tracks if bprm_set_creds has
      been called. Rename this flag and improve its comment.
      
      Cc: David Howells <dhowells@redhat.com>
      Cc: Stephen Smalley <sds@tycho.nsa.gov>
      Cc: Casey Schaufler <casey@schaufler-ca.com>
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Acked-by: NJohn Johansen <john.johansen@canonical.com>
      Acked-by: NJames Morris <james.l.morris@oracle.com>
      Acked-by: NPaul Moore <paul@paul-moore.com>
      Acked-by: NSerge Hallyn <serge@hallyn.com>
      ddb4a144
  2. 22 7月, 2017 1 次提交
  3. 21 7月, 2017 5 次提交
  4. 20 7月, 2017 8 次提交
  5. 19 7月, 2017 1 次提交
    • J
      hfsplus: Don't clear SGID when inheriting ACLs · 84969465
      Jan Kara 提交于
      When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
      set, DIR1 is expected to have SGID bit set (and owning group equal to
      the owning group of 'DIR0'). However when 'DIR0' also has some default
      ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
      'DIR1' to get cleared if user is not member of the owning group.
      
      Fix the problem by creating __hfsplus_set_posix_acl() function that does
      not call posix_acl_update_mode() and use it when inheriting ACLs. That
      prevents SGID bit clearing and the mode has been properly set by
      posix_acl_create() anyway.
      
      Fixes: 07393101
      CC: stable@vger.kernel.org
      Signed-off-by: NJan Kara <jack@suse.cz>
      84969465
  6. 18 7月, 2017 6 次提交
  7. 17 7月, 2017 4 次提交
    • Y
      ceph: fix race in concurrent readdir · 84583cfb
      Yan, Zheng 提交于
      For a large directory, program needs to issue multiple readdir
      syscalls to get all dentries. When there are multiple programs
      read the directory concurrently. Following sequence of events
      can happen.
      
       - program calls readdir with pos = 2. ceph sends readdir request
         to mds. The reply contains N1 entries. ceph adds these N1 entries
         to readdir cache.
       - program calls readdir with pos = N1+2. The readdir is satisfied
         by the readdir cache, N2 entries are returned. (Other program
         calls readdir in the middle, which fills the cache)
       - program calls readdir with pos = N1+N2+2. ceph sends readdir
         request to mds. The reply contains N3 entries and it reaches
         directory end. ceph adds these N3 entries to the readdir cache
         and marks directory complete.
      
      The second readdir call does not update fi->readdir_cache_idx.
      ceph add the last N3 entries to wrong places.
      
      Cc: stable@vger.kernel.org # v4.3+
      Signed-off-by: N"Yan, Zheng" <zyan@redhat.com>
      Signed-off-by: NIlya Dryomov <idryomov@gmail.com>
      84583cfb
    • J
      ext2: Don't clear SGID when inheriting ACLs · a992f2d3
      Jan Kara 提交于
      When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
      set, DIR1 is expected to have SGID bit set (and owning group equal to
      the owning group of 'DIR0'). However when 'DIR0' also has some default
      ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
      'DIR1' to get cleared if user is not member of the owning group.
      
      Fix the problem by creating __ext2_set_acl() function that does not call
      posix_acl_update_mode() and use it when inheriting ACLs. That prevents
      SGID bit clearing and the mode has been properly set by
      posix_acl_create() anyway.
      
      Fixes: 07393101
      CC: stable@vger.kernel.org
      CC: linux-ext4@vger.kernel.org
      Signed-off-by: NJan Kara <jack@suse.cz>
      a992f2d3
    • J
      reiserfs: Don't clear SGID when inheriting ACLs · 6883cd7f
      Jan Kara 提交于
      When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
      set, DIR1 is expected to have SGID bit set (and owning group equal to
      the owning group of 'DIR0'). However when 'DIR0' also has some default
      ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
      'DIR1' to get cleared if user is not member of the owning group.
      
      Fix the problem by moving posix_acl_update_mode() out of
      __reiserfs_set_acl() into reiserfs_set_acl(). That way the function will
      not be called when inheriting ACLs which is what we want as it prevents
      SGID bit clearing and the mode has been properly set by
      posix_acl_create() anyway.
      
      Fixes: 07393101
      CC: stable@vger.kernel.org
      CC: reiserfs-devel@vger.kernel.org
      Signed-off-by: NJan Kara <jack@suse.cz>
      6883cd7f
    • G
      binfmt_flat: Use %u to format u32 · a8605423
      Geert Uytterhoeven 提交于
      Several variables had their types changed from unsigned long to u32, but
      the printk()-style format to print them wasn't updated, leading to:
      
          fs/binfmt_flat.c: In function ‘load_flat_file’:
          fs/binfmt_flat.c:577: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘u32’
      
      Fixes: 468138d7 ("binfmt_flat: flat_{get,put}_addr_from_rp() should be able to fail")
      Signed-off-by: NGeert Uytterhoeven <geert@linux-m68k.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      a8605423
  8. 16 7月, 2017 2 次提交
  9. 15 7月, 2017 3 次提交