1. 24 Dec, 2018 1 commit
  2. 05 Dec, 2018 2 commits
    • Ondrej Mosnacek's avatar
      selinux: overhaul sidtab to fix bug and improve performance · ee1a84fd
      Ondrej Mosnacek authored
      Before this patch, during a policy reload the sidtab would become frozen
      and trying to map a new context to SID would be unable to add a new
      entry to sidtab and fail with -ENOMEM.
      
      Such failures are usually propagated into userspace, which has no way of
      distignuishing them from actual allocation failures and thus doesn't
      handle them gracefully. Such situation can be triggered e.g. by the
      following reproducer:
      
          while true; do load_policy; echo -n .; sleep 0.1; done &
          for (( i = 0; i < 1024; i++ )); do
              runcon -l s0:c$i echo -n x || break
              # or:
              # chcon -l s0:c$i <some_file> || break
          done
      
      This patch overhauls the sidtab so it doesn't need to be frozen during
      policy reload, thus solving the above problem.
      
      The new SID table leverages the fact that SIDs are allocated
      sequentially and are never invalidated and stores them in linear buckets
      indexed by a tree structure. This brings several advantages:
        1. Fast SID -> context lookup - this lookup can now be done in
           logarithmic time complexity (usually in less than 4 array lookups)
           and can still be done safely without locking.
        2. No need to re-search the whole table on reverse lookup miss - after
           acquiring the spinlock only the newly added entries need to be
           searched, which means that reverse lookups that end up inserting a
           new entry are now about twice as fast.
        3. No need to freeze sidtab during policy reload - it is now possible
           to handle insertion of new entries even during sidtab conversion.
      
      The tree structure of the new sidtab is able to grow automatically to up
      to about 2^31 entries (at which point it should not have more than about
      4 tree levels). The old sidtab had a theoretical capacity of almost 2^32
      entries, but half of that is still more than enough since by that point
      the reverse table lookups would become unusably slow anyway...
      
      The number of entries per tree node is selected automatically so that
      each node fits into a single page, which should be the easiest size for
      kmalloc() to handle.
      
      Note that the cache for reverse lookup is preserved with equivalent
      logic. The only difference is that instead of storing pointers to the
      hash table nodes it stores just the indices of the cached entries.
      
      The new cache ensures that the indices are loaded/stored atomically, but
      it still has the drawback that concurrent cache updates may mess up the
      contents of the cache. Such situation however only reduces its
      effectivity, not the correctness of lookups.
      
      Tested by selinux-testsuite and thoroughly tortured by this simple
      stress test:
      ```
      function rand_cat() {
      	echo $(( $RANDOM % 1024 ))
      }
      
      function do_work() {
      	while true; do
      		echo -n "system_u:system_r:kernel_t:s0:c$(rand_cat),c$(rand_cat)" \
      			>/sys/fs/selinux/context 2>/dev/null || true
      	done
      }
      
      do_work >/dev/null &
      do_work >/dev/null &
      do_work >/dev/null &
      
      while load_policy; do echo -n .; sleep 0.1; done
      
      kill %1
      kill %2
      kill %3
      ```
      
      Link: https://github.com/SELinuxProject/selinux-kernel/issues/38
      
      Reported-by: default avatarOrion Poplawski <orion@nwra.com>
      Reported-by: default avatarLi Kun <hw.likun@huawei.com>
      Signed-off-by: default avatarOndrej Mosnacek <omosnace@redhat.com>
      Reviewed-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      [PM: most of sidtab.c merged by hand due to conflicts]
      [PM: checkpatch fixes in mls.c, services.c, sidtab.c]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      ee1a84fd
    • Ondrej Mosnacek's avatar
      selinux: use separate table for initial SID lookup · 24ed7fda
      Ondrej Mosnacek authored
      
      
      This moves handling of initial SIDs into a separate table. Note that the
      SIDs stored in the main table are now shifted by SECINITSID_NUM and
      converted to/from the actual SIDs transparently by helper functions.
      
      This change doesn't make much sense on its own, but it simplifies
      further sidtab overhaul in a succeeding patch.
      Signed-off-by: default avatarOndrej Mosnacek <omosnace@redhat.com>
      Reviewed-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      [PM: fixed some checkpatch warnings on line length, whitespace]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      24ed7fda
  3. 26 Nov, 2018 1 commit
  4. 20 Nov, 2018 1 commit
  5. 05 Sep, 2018 1 commit
    • Jann Horn's avatar
      selinux: refactor mls_context_to_sid() and make it stricter · 95ffe194
      Jann Horn authored
      
      
      The intended behavior change for this patch is to reject any MLS strings
      that contain (trailing) garbage if p->mls_enabled is true.
      
      As suggested by Paul Moore, change mls_context_to_sid() so that the two
      parts of the range are extracted before the rest of the parsing. Because
      now we don't have to scan for two different separators simultaneously
      everywhere, we can actually switch to strchr() everywhere instead of the
      open-coded loops that scan for two separators at once.
      
      mls_context_to_sid() used to signal how much of the input string was parsed
      by updating `*scontext`. However, there is actually no case in which
      mls_context_to_sid() only parses a subset of the input and still returns
      a success (other than the buggy case with a second '-' in which it
      incorrectly claims to have consumed the entire string). Turn `scontext`
      into a simple pointer argument and stop redundantly checking whether the
      entire input was consumed in string_to_context_struct(). This also lets us
      remove the `scontext_len` argument from `string_to_context_struct()`.
      Signed-off-by: default avatarJann Horn <jannh@google.com>
      [PM: minor merge fuzz in convert_context()]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      95ffe194
  6. 19 Jun, 2018 1 commit
  7. 12 Jun, 2018 1 commit
    • Kees Cook's avatar
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook authored
      
      
      The kzalloc() function has a 2-factor argument form, kcalloc(). This
      patch replaces cases of:
      
              kzalloc(a * b, gfp)
      
      with:
              kcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kzalloc(a * b * c, gfp)
      
      with:
      
              kzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kzalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc
      + kcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(sizeof(THING) * C2, ...)
      |
        kzalloc(sizeof(TYPE) * C2, ...)
      |
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(C1 * C2, ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      6396bb22
  8. 30 May, 2018 1 commit
    • Sachin Grover's avatar
      selinux: KASAN: slab-out-of-bounds in xattr_getsecurity · efe3de79
      Sachin Grover authored
      
      
      Call trace:
       [<ffffff9203a8d7a8>] dump_backtrace+0x0/0x428
       [<ffffff9203a8dbf8>] show_stack+0x28/0x38
       [<ffffff920409bfb8>] dump_stack+0xd4/0x124
       [<ffffff9203d187e8>] print_address_description+0x68/0x258
       [<ffffff9203d18c00>] kasan_report.part.2+0x228/0x2f0
       [<ffffff9203d1927c>] kasan_report+0x5c/0x70
       [<ffffff9203d1776c>] check_memory_region+0x12c/0x1c0
       [<ffffff9203d17cdc>] memcpy+0x34/0x68
       [<ffffff9203d75348>] xattr_getsecurity+0xe0/0x160
       [<ffffff9203d75490>] vfs_getxattr+0xc8/0x120
       [<ffffff9203d75d68>] getxattr+0x100/0x2c8
       [<ffffff9203d76fb4>] SyS_fgetxattr+0x64/0xa0
       [<ffffff9203a83f70>] el0_svc_naked+0x24/0x28
      
      If user get root access and calls security.selinux setxattr() with an
      embedded NUL on a file and then if some process performs a getxattr()
      on that file with a length greater than the actual length of the string,
      it would result in a panic.
      
      To fix this, add the actual length of the string to the security context
      instead of the length passed by the userspace process.
      Signed-off-by: default avatarSachin Grover <sgrover@codeaurora.org>
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      efe3de79
  9. 14 May, 2018 1 commit
  10. 20 Mar, 2018 2 commits
  11. 02 Mar, 2018 1 commit
  12. 01 Mar, 2018 1 commit
    • Stephen Smalley's avatar
      selinux: wrap global selinux state · aa8e712c
      Stephen Smalley authored
      
      
      Define a selinux state structure (struct selinux_state) for
      global SELinux state and pass it explicitly to all security server
      functions.  The public portion of the structure contains state
      that is used throughout the SELinux code, such as the enforcing mode.
      The structure also contains a pointer to a selinux_ss structure whose
      definition is private to the security server and contains security
      server specific state such as the policy database and SID table.
      
      This change should have no effect on SELinux behavior or APIs
      (userspace or LSM).  It merely wraps SELinux state and passes it
      explicitly as needed.
      Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      [PM: minor fixups needed due to collisions with the SCTP patches]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      aa8e712c
  13. 05 Dec, 2017 1 commit
  14. 28 Nov, 2017 1 commit
  15. 20 Sep, 2017 1 commit
  16. 17 Aug, 2017 1 commit
  17. 02 Aug, 2017 1 commit
    • Stephen Smalley's avatar
      selinux: Generalize support for NNP/nosuid SELinux domain transitions · af63f419
      Stephen Smalley authored
      As systemd ramps up enabling NNP (NoNewPrivileges) for system services,
      it is increasingly breaking SELinux domain transitions for those services
      and their descendants.  systemd enables NNP not only for services whose
      unit files explicitly specify NoNewPrivileges=yes but also for services
      whose unit files specify any of the following options in combination with
      running without CAP_SYS_ADMIN (e.g. specifying User= or a
      CapabilityBoundingSet= without CAP_SYS_ADMIN): SystemCallFilter=,
      SystemCallArchitectures=, RestrictAddressFamilies=, RestrictNamespaces=,
      PrivateDevices=, ProtectKernelTunables=, ProtectKernelModules=,
      MemoryDenyWriteExecute=, or RestrictRealtime= as per the systemd.exec(5)
      man page.
      
      The end result is bad for the security of both SELinux-disabled and
      SELinux-enabled systems.  Packagers have to turn off these
      options in the unit files to preserve SELinux domain transitions.  For
      users who choose to disable SELinux, this means that they miss out on
      at least having the systemd-supported protections.  For users who keep
      SELinux enabled, they may still be missing out on some protections
      because it isn't necessarily guaranteed that the SELinux policy for
      that service provides the same protections in all cases.
      
      commit 7b0d0b40
      
       ("selinux: Permit bounded transitions under
      NO_NEW_PRIVS or NOSUID.") allowed bounded transitions under NNP in
      order to support limited usage for sandboxing programs.  However,
      defining typebounds for all of the affected service domains
      is impractical to implement in policy, since typebounds requires us
      to ensure that each domain is allowed everything all of its descendant
      domains are allowed, and this has to be repeated for the entire chain
      of domain transitions.  There is no way to clone all allow rules from
      descendants to their ancestors in policy currently, and doing so would
      be undesirable even if it were practical, as it requires leaking
      permissions to objects and operations into ancestor domains that could
      weaken their own security in order to allow them to the descendants
      (e.g. if a descendant requires execmem permission, then so do all of
      its ancestors; if a descendant requires execute permission to a file,
      then so do all of its ancestors; if a descendant requires read to a
      symbolic link or temporary file, then so do all of its ancestors...).
      SELinux domains are intentionally not hierarchical / bounded in this
      manner normally, and making them so would undermine their protections
      and least privilege.
      
      We have long had a similar tension with SELinux transitions and nosuid
      mounts, albeit not as severe.  Users often have had to choose between
      retaining nosuid on a mount and allowing SELinux domain transitions on
      files within those mounts.  This likewise leads to unfortunate tradeoffs
      in security.
      
      Decouple NNP/nosuid from SELinux transitions, so that we don't have to
      make a choice between them. Introduce a nnp_nosuid_transition policy
      capability that enables transitions under NNP/nosuid to be based on
      a permission (nnp_transition for NNP; nosuid_transition for nosuid)
      between the old and new contexts in addition to the current support
      for bounded transitions.  Domain transitions can then be allowed in
      policy without requiring the parent to be a strict superset of all of
      its children.
      
      With this change, systemd unit files can be left unmodified from upstream.
      SELinux-disabled and SELinux-enabled users will benefit from retaining any
      of the systemd-provided protections.  SELinux policy will only need to
      be adapted to enable the new policy capability and to allow the
      new permissions between domain pairs as appropriate.
      
      NB: Allowing nnp_transition between two contexts opens up the potential
      for the old context to subvert the new context by installing seccomp
      filters before the execve.  Allowing nosuid_transition between two contexts
      opens up the potential for a context transition to occur on a file from
      an untrusted filesystem (e.g. removable media or remote filesystem).  Use
      with care.
      Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      af63f419
  18. 09 Jun, 2017 1 commit
  19. 23 May, 2017 3 commits
  20. 29 Mar, 2017 1 commit
  21. 01 Mar, 2017 1 commit
  22. 09 Jan, 2017 1 commit
    • Stephen Smalley's avatar
      selinux: support distinctions among all network address families · da69a530
      Stephen Smalley authored
      
      
      Extend SELinux to support distinctions among all network address families
      implemented by the kernel by defining new socket security classes
      and mapping to them. Otherwise, many sockets are mapped to the generic
      socket class and are indistinguishable in policy.  This has come up
      previously with regard to selectively allowing access to bluetooth sockets,
      and more recently with regard to selectively allowing access to AF_ALG
      sockets.  Guido Trentalancia submitted a patch that took a similar approach
      to add only support for distinguishing AF_ALG sockets, but this generalizes
      his approach to handle all address families implemented by the kernel.
      Socket security classes are also added for ICMP and SCTP sockets.
      Socket security classes were not defined for AF_* values that are reserved
      but unimplemented in the kernel, e.g. AF_NETBEUI, AF_SECURITY, AF_ASH,
      AF_ECONET, AF_SNA, AF_WANPIPE.
      
      Backward compatibility is provided by only enabling the finer-grained
      socket classes if a new policy capability is set in the policy; older
      policies will behave as before.  The legacy redhat1 policy capability
      that was only ever used in testing within Fedora for ptrace_child
      is reclaimed for this purpose; as far as I can tell, this policy
      capability is not enabled in any supported distro policy.
      
      Add a pair of conditional compilation guards to detect when new AF_* values
      are added so that we can update SELinux accordingly rather than having to
      belatedly update it long after new address families are introduced.
      Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      da69a530
  23. 31 May, 2016 1 commit
    • Stephen Smalley's avatar
      selinux: Only apply bounds checking to source types · 7ea59202
      Stephen Smalley authored
      The current bounds checking of both source and target types
      requires allowing any domain that has access to the child
      domain to also have the same permissions to the parent, which
      is undesirable.  Drop the target bounds checking.
      
      KaiGai Kohei originally removed all use of target bounds in
      commit 7d52a155 ("selinux: remove dead code in
      type_attribute_bounds_av()") but this was reverted in
      commit 2ae3ba39 ("selinux: libsepol: remove dead code in
      check_avtab_hierarchy_callback()") because it would have
      required explicitly allowing the parent any permissions
      to the child that the child is allowed to itself.
      
      This change in contrast retains the logic for the case where both
      source and target types are bounded, thereby allowing access
      if the parent of the source is allowed the corresponding
      permissions to the parent of the target.  Further, this change
      reworks the logic such that we only perform a single computation
      for each case and there is no ambiguity as to how to resolve
      a bounds violation.
      
      Under the new logic, if the source type and target types are both
      bounded, then the parent of the source type must be allowed the same
      permissions to the parent of the target type.  If only the source
      type is bounded, then the parent of the source type must be allowed
      the same permissions to the target type.
      
      Examples of the new logic and comparisons with the old logic:
      1. If we have:
      	typebounds A B;
      then:
      	allow B self:process <permissions>;
      will satisfy the bounds constraint iff:
      	allow A self:process <permissions>;
      is also allowed in policy.
      
      Under the old logic, the allow rule on B satisfies the
      bounds constraint if any of the following three are allowed:
      	allow A B:process <permissions>; or
      	allow B A:process <permissions>; or
      	allow A self:process <permissions>;
      However, either of the first two ultimately require the third to
      satisfy the bounds constraint under the old logic, and therefore
      this degenerates to the same result (but is more efficient - we only
      need to perform one compute_av call).
      
      2. If we have:
      	typebounds A B;
      	typebounds A_exec B_exec;
      then:
      	allow B B_exec:file <permissions>;
      will satisfy the bounds constraint iff:
      	allow A A_exec:file <permissions>;
      is also allowed in policy.
      
      This is essentially the same as #1
      
      ; it is merely included as
      an example of dealing with object types related to a bounded domain
      in a manner that satisfies the bounds relationship.  Note that
      this approach is preferable to leaving B_exec unbounded and having:
      	allow A B_exec:file <permissions>;
      in policy because that would allow B's entrypoints to be used to
      enter A.  Similarly for _tmp or other related types.
      
      3. If we have:
      	typebounds A B;
      and an unbounded type T, then:
      	allow B T:file <permissions>;
      will satisfy the bounds constraint iff:
      	allow A T:file <permissions>;
      is allowed in policy.
      
      The old logic would have been identical for this example.
      
      4. If we have:
      	typebounds A B;
      and an unbounded domain D, then:
      	allow D B:unix_stream_socket <permissions>;
      is not subject to any bounds constraints under the new logic
      because D is not bounded.  This is desirable so that we can
      allow a domain to e.g. connectto a child domain without having
      to allow it to do the same to its parent.
      
      The old logic would have required:
      	allow D A:unix_stream_socket <permissions>;
      to also be allowed in policy.
      Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      [PM: re-wrapped description to appease checkpatch.pl]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      7ea59202
  24. 14 Apr, 2016 1 commit
    • Prarit Bhargava's avatar
      selinux: Change bool variable name to index. · 0fd71a62
      Prarit Bhargava authored
      
      
      security_get_bool_value(int bool) argument "bool" conflicts with
      in-kernel macros such as BUILD_BUG().  This patch changes this to
      index which isn't a type.
      
      Cc: Paul Moore <paul@paul-moore.com>
      Cc: Stephen Smalley <sds@tycho.nsa.gov>
      Cc: Eric Paris <eparis@parisplace.org>
      Cc: James Morris <james.l.morris@oracle.com>
      Cc: "Serge E. Hallyn" <serge@hallyn.com>
      Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
      Cc: Andrew Perepechko <anserper@ya.ru>
      Cc: Jeff Vander Stoep <jeffv@google.com>
      Cc: selinux@tycho.nsa.gov
      Cc: Eric Paris <eparis@redhat.com>
      Cc: Paul Moore <pmoore@redhat.com>
      Cc: David Howells <dhowells@redhat.com>
      Signed-off-by: default avatarPrarit Bhargava <prarit@redhat.com>
      Acked-by: default avatarDavid Howells <dhowells@redhat.com>
      [PM: wrapped description for checkpatch.pl, use "selinux:..." as subj]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      0fd71a62
  25. 24 Dec, 2015 1 commit
  26. 21 Oct, 2015 4 commits
  27. 13 Jul, 2015 1 commit
    • Jeff Vander Stoep's avatar
      selinux: extended permissions for ioctls · fa1aa143
      Jeff Vander Stoep authored
      
      
      Add extended permissions logic to selinux. Extended permissions
      provides additional permissions in 256 bit increments. Extend the
      generic ioctl permission check to use the extended permissions for
      per-command filtering. Source/target/class sets including the ioctl
      permission may additionally include a set of commands. Example:
      
      allowxperm <source> <target>:<class> ioctl unpriv_app_socket_cmds
      auditallowxperm <source> <target>:<class> ioctl priv_gpu_cmds
      
      Where unpriv_app_socket_cmds and priv_gpu_cmds are macros
      representing commonly granted sets of ioctl commands.
      
      When ioctl commands are omitted only the permissions are checked.
      This feature is intended to provide finer granularity for the ioctl
      permission that may be too imprecise. For example, the same driver
      may use ioctls to provide important and benign functionality such as
      driver version or socket type as well as dangerous capabilities such
      as debugging features, read/write/execute to physical memory or
      access to sensitive data. Per-command filtering provides a mechanism
      to reduce the attack surface of the kernel, and limit applications
      to the subset of commands required.
      
      The format of the policy binary has been modified to include ioctl
      commands, and the policy version number has been incremented to
      POLICYDB_VERSION_XPERMS_IOCTL=30 to account for the format
      change.
      
      The extended permissions logic is deliberately generic to allow
      components to be reused e.g. netlink filters
      Signed-off-by: default avatarJeff Vander Stoep <jeffv@google.com>
      Acked-by: default avatarNick Kralevich <nnk@google.com>
      Signed-off-by: default avatarPaul Moore <pmoore@redhat.com>
      fa1aa143
  28. 07 Apr, 2015 1 commit
  29. 22 Sep, 2014 1 commit
  30. 23 Jun, 2014 1 commit
    • Waiman Long's avatar
      selinux: no recursive read_lock of policy_rwlock in security_genfs_sid() · f31e7994
      Waiman Long authored
      
      
      With the introduction of fair queued rwlock, recursive read_lock()
      may hang the offending process if there is a write_lock() somewhere
      in between.
      
      With recursive read_lock checking enabled, the following error was
      reported:
      
      =============================================
      [ INFO: possible recursive locking detected ]
      3.16.0-rc1 #2 Tainted: G            E
      ---------------------------------------------
      load_policy/708 is trying to acquire lock:
       (policy_rwlock){.+.+..}, at: [<ffffffff8125b32a>]
      security_genfs_sid+0x3a/0x170
      
      but task is already holding lock:
       (policy_rwlock){.+.+..}, at: [<ffffffff8125b48c>]
      security_fs_use+0x2c/0x110
      
      other info that might help us debug this:
       Possible unsafe locking scenario:
      
             CPU0
             ----
        lock(policy_rwlock);
        lock(policy_rwlock);
      
      This patch fixes the occurrence of recursive read_lock() of
      policy_rwlock by adding a helper function __security_genfs_sid()
      which requires caller to take the lock before calling it. The
      security_fs_use() was then modified to call the new helper function.
      Signed-off-by: default avatarWaiman Long <Waiman.Long@hp.com>
      Acked-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      Signed-off-by: default avatarPaul Moore <pmoore@redhat.com>
      f31e7994
  31. 10 Mar, 2014 1 commit
    • Nikolay Aleksandrov's avatar
      selinux: add gfp argument to security_xfrm_policy_alloc and fix callers · 52a4c640
      Nikolay Aleksandrov authored
      
      
      security_xfrm_policy_alloc can be called in atomic context so the
      allocation should be done with GFP_ATOMIC. Add an argument to let the
      callers choose the appropriate way. In order to do so a gfp argument
      needs to be added to the method xfrm_policy_alloc_security in struct
      security_operations and to the internal function
      selinux_xfrm_alloc_user. After that switch to GFP_ATOMIC in the atomic
      callers and leave GFP_KERNEL as before for the rest.
      The path that needed the gfp argument addition is:
      security_xfrm_policy_alloc -> security_ops.xfrm_policy_alloc_security ->
      all users of xfrm_policy_alloc_security (e.g. selinux_xfrm_policy_alloc) ->
      selinux_xfrm_alloc_user (here the allocation used to be GFP_KERNEL only)
      
      Now adding a gfp argument to selinux_xfrm_alloc_user requires us to also
      add it to security_context_to_sid which is used inside and prior to this
      patch did only GFP_KERNEL allocation. So add gfp argument to
      security_context_to_sid and adjust all of its callers as well.
      
      CC: Paul Moore <paul@paul-moore.com>
      CC: Dave Jones <davej@redhat.com>
      CC: Steffen Klassert <steffen.klassert@secunet.com>
      CC: Fan Du <fan.du@windriver.com>
      CC: David S. Miller <davem@davemloft.net>
      CC: LSM list <linux-security-module@vger.kernel.org>
      CC: SELinux list <selinux@tycho.nsa.gov>
      Signed-off-by: default avatarNikolay Aleksandrov <nikolay@redhat.com>
      Acked-by: default avatarPaul Moore <paul@paul-moore.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      52a4c640
  32. 05 Feb, 2014 1 commit
    • Stephen Smalley's avatar
      SELinux: Fix kernel BUG on empty security contexts. · 2172fa70
      Stephen Smalley authored
      Setting an empty security context (length=0) on a file will
      lead to incorrectly dereferencing the type and other fields
      of the security context structure, yielding a kernel BUG.
      As a zero-length security context is never valid, just reject
      all such security contexts whether coming from userspace
      via setxattr or coming from the filesystem upon a getxattr
      request by SELinux.
      
      Setting a security context value (empty or otherwise) unknown to
      SELinux in the first place is only possible for a root process
      (CAP_MAC_ADMIN), and, if running SELinux in enforcing mode, only
      if the corresponding SELinux mac_admin permission is also granted
      to the domain by policy.  In Fedora policies, this is only allowed for
      specific domains such as livecd for setting down security contexts
      that are not defined in the build host policy.
      
      Reproducer:
      su
      setenforce 0
      touch foo
      setfattr -n security.selinux foo
      
      Caveat:
      Relabeling or removing foo after doing the above may not be possible
      without booting with SELinux disabled.  Any subsequent access to foo
      after doing the above will also trigger the BUG.
      
      BUG output from Matthew Thode:
      [  473.893141] ------------[ cut here ]------------
      [  473.962110] kernel BUG at security/selinux/ss/services.c:654!
      [  473.995314] invalid opcode: 0000 [#6] SMP
      [  474.027196] Modules linked in:
      [  474.058118] CPU: 0 PID: 8138 Comm: ls Tainted: G      D   I
      3.13.0-grsec #1
      
      
      [  474.116637] Hardware name: Supermicro X8ST3/X8ST3, BIOS 2.0
      07/29/10
      [  474.149768] task: ffff8805f50cd010 ti: ffff8805f50cd488 task.ti:
      ffff8805f50cd488
      [  474.183707] RIP: 0010:[<ffffffff814681c7>]  [<ffffffff814681c7>]
      context_struct_compute_av+0xce/0x308
      [  474.219954] RSP: 0018:ffff8805c0ac3c38  EFLAGS: 00010246
      [  474.252253] RAX: 0000000000000000 RBX: ffff8805c0ac3d94 RCX:
      0000000000000100
      [  474.287018] RDX: ffff8805e8aac000 RSI: 00000000ffffffff RDI:
      ffff8805e8aaa000
      [  474.321199] RBP: ffff8805c0ac3cb8 R08: 0000000000000010 R09:
      0000000000000006
      [  474.357446] R10: 0000000000000000 R11: ffff8805c567a000 R12:
      0000000000000006
      [  474.419191] R13: ffff8805c2b74e88 R14: 00000000000001da R15:
      0000000000000000
      [  474.453816] FS:  00007f2e75220800(0000) GS:ffff88061fc00000(0000)
      knlGS:0000000000000000
      [  474.489254] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  474.522215] CR2: 00007f2e74716090 CR3: 00000005c085e000 CR4:
      00000000000207f0
      [  474.556058] Stack:
      [  474.584325]  ffff8805c0ac3c98 ffffffff811b549b ffff8805c0ac3c98
      ffff8805f1190a40
      [  474.618913]  ffff8805a6202f08 ffff8805c2b74e88 00068800d0464990
      ffff8805e8aac860
      [  474.653955]  ffff8805c0ac3cb8 000700068113833a ffff880606c75060
      ffff8805c0ac3d94
      [  474.690461] Call Trace:
      [  474.723779]  [<ffffffff811b549b>] ? lookup_fast+0x1cd/0x22a
      [  474.778049]  [<ffffffff81468824>] security_compute_av+0xf4/0x20b
      [  474.811398]  [<ffffffff8196f419>] avc_compute_av+0x2a/0x179
      [  474.843813]  [<ffffffff8145727b>] avc_has_perm+0x45/0xf4
      [  474.875694]  [<ffffffff81457d0e>] inode_has_perm+0x2a/0x31
      [  474.907370]  [<ffffffff81457e76>] selinux_inode_getattr+0x3c/0x3e
      [  474.938726]  [<ffffffff81455cf6>] security_inode_getattr+0x1b/0x22
      [  474.970036]  [<ffffffff811b057d>] vfs_getattr+0x19/0x2d
      [  475.000618]  [<ffffffff811b05e5>] vfs_fstatat+0x54/0x91
      [  475.030402]  [<ffffffff811b063b>] vfs_lstat+0x19/0x1b
      [  475.061097]  [<ffffffff811b077e>] SyS_newlstat+0x15/0x30
      [  475.094595]  [<ffffffff8113c5c1>] ? __audit_syscall_entry+0xa1/0xc3
      [  475.148405]  [<ffffffff8197791e>] system_call_fastpath+0x16/0x1b
      [  475.179201] Code: 00 48 85 c0 48 89 45 b8 75 02 0f 0b 48 8b 45 a0 48
      8b 3d 45 d0 b6 00 8b 40 08 89 c6 ff ce e8 d1 b0 06 00 48 85 c0 49 89 c7
      75 02 <0f> 0b 48 8b 45 b8 4c 8b 28 eb 1e 49 8d 7d 08 be 80 01 00 00 e8
      [  475.255884] RIP  [<ffffffff814681c7>]
      context_struct_compute_av+0xce/0x308
      [  475.296120]  RSP <ffff8805c0ac3c38>
      [  475.328734] ---[ end trace f076482e9d754adc ]---
      Reported-by: default avatarMatthew Thode <mthode@mthode.org>
      Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarPaul Moore <pmoore@redhat.com>
      2172fa70
  33. 14 Jan, 2014 1 commit