1. 11 5月, 2021 1 次提交
    • J
      selinux: Remove redundant assignment to rc · fd781f45
      Jiapeng Chong 提交于
      Variable rc is set to '-EINVAL' but this value is never read as
      it is overwritten or not used later on, hence it is a redundant
      assignment and can be removed.
      
      Cleans up the following clang-analyzer warning:
      
      security/selinux/ss/services.c:2103:3: warning: Value stored to 'rc' is
      never read [clang-analyzer-deadcode.DeadStores].
      
      security/selinux/ss/services.c:2079:2: warning: Value stored to 'rc' is
      never read [clang-analyzer-deadcode.DeadStores].
      
      security/selinux/ss/services.c:2071:2: warning: Value stored to 'rc' is
      never read [clang-analyzer-deadcode.DeadStores].
      
      security/selinux/ss/services.c:2062:2: warning: Value stored to 'rc' is
      never read [clang-analyzer-deadcode.DeadStores].
      
      security/selinux/ss/policydb.c:2592:3: warning: Value stored to 'rc' is
      never read [clang-analyzer-deadcode.DeadStores].
      Reported-by: NAbaci Robot <abaci@linux.alibaba.com>
      Signed-off-by: NJiapeng Chong <jiapeng.chong@linux.alibaba.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      fd781f45
  2. 23 4月, 2021 1 次提交
  3. 08 4月, 2021 1 次提交
    • O
      selinux: fix race between old and new sidtab · 9ad6e9cb
      Ondrej Mosnacek 提交于
      Since commit 1b8b31a2 ("selinux: convert policy read-write lock to
      RCU"), there is a small window during policy load where the new policy
      pointer has already been installed, but some threads may still be
      holding the old policy pointer in their read-side RCU critical sections.
      This means that there may be conflicting attempts to add a new SID entry
      to both tables via sidtab_context_to_sid().
      
      See also (and the rest of the thread):
      https://lore.kernel.org/selinux/CAFqZXNvfux46_f8gnvVvRYMKoes24nwm2n3sPbMjrB8vKTW00g@mail.gmail.com/
      
      Fix this by installing the new policy pointer under the old sidtab's
      spinlock along with marking the old sidtab as "frozen". Then, if an
      attempt to add new entry to a "frozen" sidtab is detected, make
      sidtab_context_to_sid() return -ESTALE to indicate that a new policy
      has been installed and that the caller will have to abort the policy
      transaction and try again after re-taking the policy pointer (which is
      guaranteed to be a newer policy). This requires adding a retry-on-ESTALE
      logic to all callers of sidtab_context_to_sid(), but fortunately these
      are easy to determine and aren't that many.
      
      This seems to be the simplest solution for this problem, even if it
      looks somewhat ugly. Note that other places in the kernel (e.g.
      do_mknodat() in fs/namei.c) use similar stale-retry patterns, so I think
      it's reasonable.
      
      Cc: stable@vger.kernel.org
      Fixes: 1b8b31a2 ("selinux: convert policy read-write lock to RCU")
      Signed-off-by: NOndrej Mosnacek <omosnace@redhat.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      9ad6e9cb
  4. 19 3月, 2021 1 次提交
    • O
      selinux: fix variable scope issue in live sidtab conversion · 6406887a
      Ondrej Mosnacek 提交于
      Commit 02a52c5c ("selinux: move policy commit after updating
      selinuxfs") moved the selinux_policy_commit() call out of
      security_load_policy() into sel_write_load(), which caused a subtle yet
      rather serious bug.
      
      The problem is that security_load_policy() passes a reference to the
      convert_params local variable to sidtab_convert(), which stores it in
      the sidtab, where it may be accessed until the policy is swapped over
      and RCU synchronized. Before 02a52c5c, selinux_policy_commit() was
      called directly from security_load_policy(), so the convert_params
      pointer remained valid all the way until the old sidtab was destroyed,
      but now that's no longer the case and calls to sidtab_context_to_sid()
      on the old sidtab after security_load_policy() returns may cause invalid
      memory accesses.
      
      This can be easily triggered using the stress test from commit
      ee1a84fd ("selinux: overhaul sidtab to fix bug and improve
      performance"):
      ```
      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
      ```
      
      Fix this by allocating the temporary sidtab convert structures
      dynamically and passing them among the
      selinux_policy_{load,cancel,commit} functions.
      
      Fixes: 02a52c5c ("selinux: move policy commit after updating selinuxfs")
      Cc: stable@vger.kernel.org
      Tested-by: NTyler Hicks <tyhicks@linux.microsoft.com>
      Reviewed-by: NTyler Hicks <tyhicks@linux.microsoft.com>
      Signed-off-by: NOndrej Mosnacek <omosnace@redhat.com>
      [PM: merge fuzz in security.h and services.c]
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      6406887a
  5. 09 3月, 2021 1 次提交
    • L
      selinux: measure state and policy capabilities · 2554a48f
      Lakshmi Ramasubramanian 提交于
      SELinux stores the configuration state and the policy capabilities
      in kernel memory.  Changes to this data at runtime would have an impact
      on the security guarantees provided by SELinux.  Measuring this data
      through IMA subsystem provides a tamper-resistant way for
      an attestation service to remotely validate it at runtime.
      
      Measure the configuration state and policy capabilities by calling
      the IMA hook ima_measure_critical_data().
      
      To enable SELinux data measurement, the following steps are required:
      
       1, Add "ima_policy=critical_data" to the kernel command line arguments
          to enable measuring SELinux data at boot time.
          For example,
            BOOT_IMAGE=/boot/vmlinuz-5.11.0-rc3+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset security=selinux ima_policy=critical_data
      
       2, Add the following rule to /etc/ima/ima-policy
             measure func=CRITICAL_DATA label=selinux
      
      Sample measurement of SELinux state and policy capabilities:
      
      10 2122...65d8 ima-buf sha256:13c2...1292 selinux-state 696e...303b
      
      Execute the following command to extract the measured data
      from the IMA's runtime measurements list:
      
        grep "selinux-state" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | tail -1 | cut -d' ' -f 6 | xxd -r -p
      
      The output should be a list of key-value pairs. For example,
       initialized=1;enforcing=0;checkreqprot=1;network_peer_controls=1;open_perms=1;extended_socket_class=1;always_check_network=0;cgroup_seclabel=1;nnp_nosuid_transition=1;genfs_seclabel_symlinks=0;
      
      To verify the measurement is consistent with the current SELinux state
      reported on the system, compare the integer values in the following
      files with those set in the IMA measurement (using the following commands):
      
       - cat /sys/fs/selinux/enforce
       - cat /sys/fs/selinux/checkreqprot
       - cat /sys/fs/selinux/policy_capabilities/[capability_file]
      
      Note that the actual verification would be against an expected state
      and done on a separate system (likely an attestation server) requiring
      "initialized=1;enforcing=1;checkreqprot=0;"
      for a secure state and then whatever policy capabilities are actually
      set in the expected policy (which can be extracted from the policy
      itself via seinfo, for example).
      Signed-off-by: NLakshmi Ramasubramanian <nramas@linux.microsoft.com>
      Suggested-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Suggested-by: NPaul Moore <paul@paul-moore.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      2554a48f
  6. 15 1月, 2021 1 次提交
    • L
      selinux: include a consumer of the new IMA critical data hook · fdd1ffe8
      Lakshmi Ramasubramanian 提交于
      SELinux stores the active policy in memory, so the changes to this data
      at runtime would have an impact on the security guarantees provided
      by SELinux.  Measuring in-memory SELinux policy through IMA subsystem
      provides a secure way for the attestation service to remotely validate
      the policy contents at runtime.
      
      Measure the hash of the loaded policy by calling the IMA hook
      ima_measure_critical_data().  Since the size of the loaded policy
      can be large (several MB), measure the hash of the policy instead of
      the entire policy to avoid bloating the IMA log entry.
      
      To enable SELinux data measurement, the following steps are required:
      
      1, Add "ima_policy=critical_data" to the kernel command line arguments
         to enable measuring SELinux data at boot time.
      For example,
        BOOT_IMAGE=/boot/vmlinuz-5.10.0-rc1+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset security=selinux ima_policy=critical_data
      
      2, Add the following rule to /etc/ima/ima-policy
         measure func=CRITICAL_DATA label=selinux
      
      Sample measurement of the hash of SELinux policy:
      
      To verify the measured data with the current SELinux policy run
      the following commands and verify the output hash values match.
      
        sha256sum /sys/fs/selinux/policy | cut -d' ' -f 1
      
        grep "selinux-policy-hash" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | tail -1 | cut -d' ' -f 6
      
      Note that the actual verification of SELinux policy would require loading
      the expected policy into an identical kernel on a pristine/known-safe
      system and run the sha256sum /sys/kernel/selinux/policy there to get
      the expected hash.
      Signed-off-by: NLakshmi Ramasubramanian <nramas@linux.microsoft.com>
      Suggested-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Acked-by: NPaul Moore <paul@paul-moore.com>
      Reviewed-by: NTyler Hicks <tyhicks@linux.microsoft.com>
      Signed-off-by: NMimi Zohar <zohar@linux.ibm.com>
      fdd1ffe8
  7. 12 1月, 2021 1 次提交
  8. 28 10月, 2020 1 次提交
  9. 11 9月, 2020 1 次提交
  10. 31 8月, 2020 1 次提交
  11. 27 8月, 2020 1 次提交
  12. 26 8月, 2020 1 次提交
    • D
      selinux: fix error handling bugs in security_load_policy() · 0256b0aa
      Dan Carpenter 提交于
      There are a few bugs in the error handling for security_load_policy().
      
      1) If the newpolicy->sidtab allocation fails then it leads to a NULL
         dereference.  Also the error code was not set to -ENOMEM on that
         path.
      2) If policydb_read() failed then we call policydb_destroy() twice
         which meands we call kvfree(p->sym_val_to_name[i]) twice.
      3) If policydb_load_isids() failed then we call sidtab_destroy() twice
         and that results in a double free in the sidtab_destroy_tree()
         function because entry.ptr_inner and entry.ptr_leaf are not set to
         NULL.
      
      One thing that makes this code nice to deal with is that none of the
      functions return partially allocated data.  In other words, the
      policydb_read() either allocates everything successfully or it frees
      all the data it allocates.  It never returns a mix of allocated and
      not allocated data.
      
      I re-wrote this to only free the successfully allocated data which
      avoids the double frees.  I also re-ordered selinux_policy_free() so
      it's in the reverse order of the allocation function.
      
      Fixes: c7c556f1 ("selinux: refactor changing booleans")
      Acked-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: NDan Carpenter <dan.carpenter@oracle.com>
      [PM: partially merged by hand due to merge fuzz]
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      0256b0aa
  13. 25 8月, 2020 1 次提交
  14. 20 8月, 2020 1 次提交
  15. 19 8月, 2020 1 次提交
  16. 18 8月, 2020 4 次提交
    • S
      selinux: refactor changing booleans · c7c556f1
      Stephen Smalley 提交于
      Refactor the logic for changing SELinux policy booleans in a similar
      manner to the refactoring of policy load, thereby reducing the
      size of the critical section when the policy write-lock is held
      and making it easier to convert the policy rwlock to RCU in the
      future.  Instead of directly modifying the policydb in place, modify
      a copy and then swap it into place through a single pointer update.
      Only fully copy the portions of the policydb that are affected by
      boolean changes to avoid the full cost of a deep policydb copy.
      Introduce another level of indirection for the sidtab since changing
      booleans does not require updating the sidtab, unlike policy load.
      While we are here, create a common helper for notifying
      other kernel components and userspace of a policy change and call it
      from both security_set_bools() and selinux_policy_commit().
      
      Based on an old (2004) patch by Kaigai Kohei [1] to convert the policy
      rwlock to RCU that was deferred at the time since it did not
      significantly improve performance and introduced complexity. Peter
      Enderborg later submitted a patch series to convert to RCU [2] that
      would have made changing booleans a much more expensive operation
      by requiring a full policydb_write();policydb_read(); sequence to
      deep copy the entire policydb and also had concerns regarding
      atomic allocations.
      
      This change is now simplified by the earlier work to encapsulate
      policy state in the selinux_policy struct and to refactor
      policy load.  After this change, the last major obstacle to
      converting the policy rwlock to RCU is likely the sidtab live
      convert support.
      
      [1] https://lore.kernel.org/selinux/6e2f9128-e191-ebb3-0e87-74bfccb0767f@tycho.nsa.gov/
      [2] https://lore.kernel.org/selinux/20180530141104.28569-1-peter.enderborg@sony.com/Signed-off-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      c7c556f1
    • S
      selinux: move policy commit after updating selinuxfs · 02a52c5c
      Stephen Smalley 提交于
      With the refactoring of the policy load logic in the security
      server from the previous change, it is now possible to split out
      the committing of the new policy from security_load_policy() and
      perform it only after successful updating of selinuxfs.  Change
      security_load_policy() to return the newly populated policy
      data structures to the caller, export selinux_policy_commit()
      for external callers, and introduce selinux_policy_cancel() to
      provide a way to cancel the policy load in the event of an error
      during updating of the selinuxfs directory tree.  Further, rework
      the interfaces used by selinuxfs to get information from the policy
      when creating the new directory tree to take and act upon the
      new policy data structure rather than the current/active policy.
      Update selinuxfs to use these updated and new interfaces.  While
      we are here, stop re-creating the policy_capabilities directory
      on each policy load since it does not depend on the policy, and
      stop trying to create the booleans and classes directories during
      the initial creation of selinuxfs since no information is available
      until first policy load.
      
      After this change, a failure while updating the booleans and class
      directories will cause the entire policy load to be canceled, leaving
      the original policy intact, and policy load notifications to userspace
      will only happen after a successful completion of updating those
      directories.  This does not (yet) provide full atomicity with respect
      to the updating of the directory trees themselves.
      Signed-off-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      02a52c5c
    • S
      selinux: encapsulate policy state, refactor policy load · 46169802
      Stephen Smalley 提交于
      Encapsulate the policy state in its own structure (struct
      selinux_policy) that is separately allocated but referenced from the
      selinux_ss structure.  The policy state includes the SID table
      (particularly the context structures), the policy database, and the
      mapping between the kernel classes/permissions and the policy values.
      Refactor the security server portion of the policy load logic to
      cleanly separate loading of the new structures from committing the new
      policy.  Unify the initial policy load and reload code paths as much
      as possible, avoiding duplicated code.  Make sure we are taking the
      policy read-lock prior to any dereferencing of the policy.  Move the
      copying of the policy capability booleans into the state structure
      outside of the policy write-lock because they are separate from the
      policy and are read outside of any policy lock; possibly they should
      be using at least READ_ONCE/WRITE_ONCE or smp_load_acquire/store_release.
      
      These changes simplify the policy loading logic, reduce the size of
      the critical section while holding the policy write-lock, and should
      facilitate future changes to e.g. refactor the entire policy reload
      logic including the selinuxfs code to make the updating of the policy
      and the selinuxfs directory tree atomic and/or to convert the policy
      read-write lock to RCU.
      Signed-off-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      46169802
    • S
      scripts/selinux,selinux: update mdp to enable policy capabilities · 339949be
      Stephen Smalley 提交于
      Presently mdp does not enable any SELinux policy capabilities
      in the dummy policy it generates. Thus, policies derived from
      it will by default lack various features commonly used in modern
      policies such as open permission, extended socket classes, network
      peer controls, etc.  Split the policy capability definitions out into
      their own headers so that we can include them into mdp without pulling in
      other kernel headers and extend mdp generate policycap statements for the
      policy capabilities known to the kernel.  Policy authors may wish to
      selectively remove some of these from the generated policy.
      Signed-off-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      339949be
  17. 10 7月, 2020 1 次提交
    • O
      selinux: prepare for inlining of hashtab functions · 24def7bb
      Ondrej Mosnacek 提交于
      Refactor searching and inserting into hashtabs to pave the way for
      converting hashtab_search() and hashtab_insert() to inline functions in
      the next patch. This will avoid indirect calls and allow the compiler to
      better optimize individual callers, leading to a significant performance
      improvement.
      
      In order to avoid the indirect calls, the key hashing and comparison
      callbacks need to be extracted from the hashtab struct and passed
      directly to hashtab_search()/_insert() by the callers so that the
      callback address is always known at compile time. The kernel's
      rhashtable library (<linux/rhashtable*.h>) does the same thing.
      
      This of course makes the hashtab functions slightly easier to misuse by
      passing a wrong callback set, but unfortunately there is no better way
      to implement a hash table that is both generic and efficient in C. This
      patch tries to somewhat mitigate this by only calling the hashtab
      functions in the same file where the corresponding callbacks are
      defined (wrapping them into more specialized functions as needed).
      
      Note that this patch doesn't bring any benefit without also moving the
      definitions of hashtab_search() and -_insert() to the header file, which
      is done in a follow-up patch for easier review of the hashtab.c changes
      in this patch.
      Signed-off-by: NOndrej Mosnacek <omosnace@redhat.com>
      Acked-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      24def7bb
  18. 09 7月, 2020 1 次提交
  19. 11 6月, 2020 1 次提交
    • T
      selinux: fix double free · 65de5096
      Tom Rix 提交于
      Clang's static analysis tool reports these double free memory errors.
      
      security/selinux/ss/services.c:2987:4: warning: Attempt to free released memory [unix.Malloc]
                              kfree(bnames[i]);
                              ^~~~~~~~~~~~~~~~
      security/selinux/ss/services.c:2990:2: warning: Attempt to free released memory [unix.Malloc]
              kfree(bvalues);
              ^~~~~~~~~~~~~~
      
      So improve the security_get_bools error handling by freeing these variables
      and setting their return pointers to NULL and the return len to 0
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NTom Rix <trix@redhat.com>
      Acked-by: NStephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      65de5096
  20. 02 5月, 2020 1 次提交
  21. 18 4月, 2020 3 次提交
  22. 15 4月, 2020 1 次提交
  23. 28 2月, 2020 1 次提交
    • S
      selinux: remove unused initial SIDs and improve handling · e3e0b582
      Stephen Smalley 提交于
      Remove initial SIDs that have never been used or are no longer used by
      the kernel from its string table, which is also used to generate the
      SECINITSID_* symbols referenced in code.  Update the code to
      gracefully handle the fact that these can now be NULL. Stop treating
      it as an error if a policy defines additional initial SIDs unknown to
      the kernel.  Do not load unused initial SID contexts into the sidtab.
      Fix the incorrect usage of the name from the ocontext in error
      messages when loading initial SIDs since these are not presently
      written to the kernel policy and are therefore always NULL.
      
      After this change, it is possible to safely reclaim and reuse some of
      the unused initial SIDs without compatibility issues.  Specifically,
      unused initial SIDs that were being assigned the same context as the
      unlabeled initial SID in policies can be reclaimed and reused for
      another purpose, with existing policies still treating them as having
      the unlabeled context and future policies having the option of mapping
      them to a more specific context.  For example, this could have been
      used when the infiniband labeling support was introduced to define
      initial SIDs for the default pkey and endport SIDs similar to the
      handling of port/netif/node SIDs rather than always using
      SECINITSID_UNLABELED as the default.
      
      The set of safely reclaimable unused initial SIDs across all known
      policies is igmp_packet (13), icmp_socket (14), tcp_socket (15), kmod
      (24), policy (25), and scmp_packet (26); these initial SIDs were
      assigned the same context as unlabeled in all known policies including
      mls.  If only considering non-mls policies (i.e. assuming that mls
      users always upgrade policy with their kernels), the set of safely
      reclaimable unused initial SIDs further includes file_labels (6), init
      (7), sysctl_modprobe (16), and sysctl_fs (18) through sysctl_dev (23).
      
      Adding new initial SIDs beyond SECINITSID_NUM to policy unfortunately
      became a fatal error in commit 24ed7fda ("selinux: use separate
      table for initial SID lookup") and even before that it could cause
      problems on a policy reload (collision between the new initial SID and
      one allocated at runtime) ever since commit 42596eaf ("selinux:
      load the initial SIDs upon every policy load") so we cannot safely
      start adding new initial SIDs to policies beyond SECINITSID_NUM (27)
      until such a time as all such kernels do not need to be supported and
      only those that include this commit are relevant. That is not a big
      deal since we haven't added a new initial SID since 2004 (v2.6.7) and
      we have plenty of unused ones we can reclaim if we truly need one.
      
      If we want to avoid the wasted storage in initial_sid_to_string[]
      and/or sidtab->isids[] for the unused initial SIDs, we could introduce
      an indirection between the kernel initial SID values and the policy
      initial SID values and just map the policy SID values in the ocontexts
      to the kernel values during policy_load_isids(). Originally I thought
      we'd do this by preserving the initial SID names in the kernel policy
      and creating a mapping at load time like we do for the security
      classes and permissions but that would require a new kernel policy
      format version and associated changes to libsepol/checkpolicy and I'm
      not sure it is justified. Simpler approach is just to create a fixed
      mapping table in the kernel from the existing fixed policy values to
      the kernel values. Less flexible but probably sufficient.
      
      A separate selinux userspace change was applied in
      https://github.com/SELinuxProject/selinux/commit/8677ce5e8f592950ae6f14cea1b68a20ddc1ac25
      to enable removal of most of the unused initial SID contexts from
      policies, but there is no dependency between that change and this one.
      That change permits removing all of the unused initial SID contexts
      from policy except for the fs and sysctl SID contexts.  The initial
      SID declarations themselves would remain in policy to preserve the
      values of subsequent ones but the contexts can be dropped.  If/when
      the kernel decides to reuse one of them, future policies can change
      the name and start assigning a context again without breaking
      compatibility.
      
      Here is how I would envision staging changes to the initial SIDs in a
      compatible manner after this commit is applied:
      
      1. At any time after this commit is applied, the kernel could choose
      to reclaim one of the safely reclaimable unused initial SIDs listed
      above for a new purpose (i.e. replace its NULL entry in the
      initial_sid_to_string[] table with a new name and start using the
      newly generated SECINITSID_name symbol in code), and refpolicy could
      at that time rename its declaration of that initial SID to reflect its
      new purpose and start assigning it a context going
      forward. Existing/old policies would map the reclaimed initial SID to
      the unlabeled context, so that would be the initial default behavior
      until policies are updated. This doesn't depend on the selinux
      userspace change; it will work with existing policies and userspace.
      
      2. In 6 months or so we'll have another SELinux userspace release that
      will include the libsepol/checkpolicy support for omitting unused
      initial SID contexts.
      
      3. At any time after that release, refpolicy can make that release its
      minimum build requirement and drop the sid context statements (but not
      the sid declarations) for all of the unused initial SIDs except for
      fs and sysctl, which must remain for compatibility on policy
      reload with old kernels and for compatibility with kernels that were
      still using SECINITSID_SYSCTL (< 2.6.39). This doesn't depend on this
      kernel commit; it will work with previous kernels as well.
      
      4. After N years for some value of N, refpolicy decides that it no
      longer cares about policy reload compatibility for kernels that
      predate this kernel commit, and refpolicy drops the fs and sysctl
      SID contexts from policy too (but retains the declarations).
      
      5. After M years for some value of M, the kernel decides that it no
      longer cares about compatibility with refpolicies that predate step 4
      (dropping the fs and sysctl SIDs), and those two SIDs also become
      safely reclaimable.  This step is optional and need not ever occur unless
      we decide that the need to reclaim those two SIDs outweighs the
      compatibility cost.
      
      6. After O years for some value of O, refpolicy decides that it no
      longer cares about policy load (not just reload) compatibility for
      kernels that predate this kernel commit, and both kernel and refpolicy
      can then start adding and using new initial SIDs beyond 27. This does
      not depend on the previous change (step 5) and can occur independent
      of it.
      
      Fixes: https://github.com/SELinuxProject/selinux-kernel/issues/12Signed-off-by: NStephen Smalley <sds@tycho.nsa.gov>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      e3e0b582
  24. 23 2月, 2020 1 次提交
    • O
      selinux: optimize storage of filename transitions · c3a27611
      Ondrej Mosnacek 提交于
      In these rules, each rule with the same (target type, target class,
      filename) values is (in practice) always mapped to the same result type.
      Therefore, it is much more efficient to group the rules by (ttype,
      tclass, filename).
      
      Thus, this patch drops the stype field from the key and changes the
      datum to be a linked list of one or more structures that contain a
      result type and an ebitmap of source types that map the given target to
      the given result type under the given filename. The size of the hash
      table is also incremented to 2048 to be more optimal for Fedora policy
      (which currently has ~2500 unique (ttype, tclass, filename) tuples,
      regardless of whether the 'unconfined' module is enabled).
      
      Not only does this dramtically reduce memory usage when the policy
      contains a lot of unconfined domains (ergo a lot of filename based
      transitions), but it also slightly reduces memory usage of strongly
      confined policies (modeled on Fedora policy with 'unconfined' module
      disabled) and significantly reduces lookup times of these rules on
      Fedora (roughly matches the performance of the rhashtable conversion
      patch [1] posted recently to selinux@vger.kernel.org).
      
      An obvious next step is to change binary policy format to match this
      layout, so that disk space is also saved. However, since that requires
      more work (including matching userspace changes) and this patch is
      already beneficial on its own, I'm posting it separately.
      
      Performance/memory usage comparison:
      
      Kernel           | Policy load | Policy load   | Mem usage | Mem usage     | openbench
                       |             | (-unconfined) |           | (-unconfined) | (createfiles)
      -----------------|-------------|---------------|-----------|---------------|--------------
      reference        |       1,30s |         0,91s |      90MB |          77MB | 55 us/file
      rhashtable patch |       0.98s |         0,85s |      85MB |          75MB | 38 us/file
      this patch       |       0,95s |         0,87s |      75MB |          75MB | 40 us/file
      
      (Memory usage is measured after boot. With SELinux disabled the memory
      usage was ~60MB on the same system.)
      
      [1] https://lore.kernel.org/selinux/20200116213937.77795-1-dev@lynxeye.de/T/Signed-off-by: NOndrej Mosnacek <omosnace@redhat.com>
      Acked-by: NStephen Smalley <sds@tycho.nsa.gov>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      c3a27611
  25. 12 2月, 2020 2 次提交
  26. 10 2月, 2020 3 次提交
  27. 17 1月, 2020 1 次提交
  28. 11 1月, 2020 1 次提交
  29. 25 12月, 2019 1 次提交
    • Y
      selinux: remove set but not used variable 'sidtab' · f1268534
      YueHaibing 提交于
      security/selinux/ss/services.c: In function security_port_sid:
      security/selinux/ss/services.c:2346:17: warning: variable sidtab set but not used [-Wunused-but-set-variable]
      security/selinux/ss/services.c: In function security_ib_endport_sid:
      security/selinux/ss/services.c:2435:17: warning: variable sidtab set but not used [-Wunused-but-set-variable]
      security/selinux/ss/services.c: In function security_netif_sid:
      security/selinux/ss/services.c:2480:17: warning: variable sidtab set but not used [-Wunused-but-set-variable]
      security/selinux/ss/services.c: In function security_fs_use:
      security/selinux/ss/services.c:2831:17: warning: variable sidtab set but not used [-Wunused-but-set-variable]
      
      Since commit 66f8e2f0 ("selinux: sidtab reverse lookup hash table")
      'sidtab' is not used any more, so remove it.
      Reported-by: NHulk Robot <hulkci@huawei.com>
      Signed-off-by: NYueHaibing <yuehaibing@huawei.com>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      f1268534
  30. 24 12月, 2019 1 次提交
  31. 10 12月, 2019 2 次提交
    • O
      selinux: cache the SID -> context string translation · d97bd23c
      Ondrej Mosnacek 提交于
      Translating a context struct to string can be quite slow, especially if
      the context has a lot of category bits set. This can cause quite
      noticeable performance impact in situations where the translation needs
      to be done repeatedly. A common example is a UNIX datagram socket with
      the SO_PASSSEC option enabled, which is used e.g. by systemd-journald
      when receiving log messages via datagram socket. This scenario can be
      reproduced with:
      
          cat /dev/urandom | base64 | logger &
          timeout 30s perf record -p $(pidof systemd-journald) -a -g
          kill %1
          perf report -g none --pretty raw | grep security_secid_to_secctx
      
      Before the caching introduced by this patch, computing the context
      string (security_secid_to_secctx() function) takes up ~65% of
      systemd-journald's CPU time (assuming a context with 1024 categories
      set and Fedora x86_64 release kernel configs). After this patch
      (assuming near-perfect cache hit ratio) this overhead is reduced to just
      ~2%.
      
      This patch addresses the issue by caching a certain number (compile-time
      configurable) of recently used context strings to speed up repeated
      translations of the same context, while using only a small amount of
      memory.
      
      The cache is integrated into the existing sidtab table by adding a field
      to each entry, which when not NULL contains an RCU-protected pointer to
      a cache entry containing the cached string. The cache entries are kept
      in a linked list sorted according to how recently they were used. On a
      cache miss when the cache is full, the least recently used entry is
      removed to make space for the new entry.
      
      The patch migrates security_sid_to_context_core() to use the cache (also
      a few other functions where it was possible without too much fuss, but
      these mostly use the translation for logging in case of error, which is
      rare).
      
      Link: https://bugzilla.redhat.com/show_bug.cgi?id=1733259
      Cc: Michal Sekletar <msekleta@redhat.com>
      Signed-off-by: NOndrej Mosnacek <omosnace@redhat.com>
      Reviewed-by: NStephen Smalley <sds@tycho.nsa.gov>
      Tested-by: NStephen Smalley <sds@tycho.nsa.gov>
      Reviewed-by: NPaul E. McKenney <paulmck@kernel.org>
      [PM: lots of merge fixups due to collisions with other sidtab patches]
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      d97bd23c
    • J
      selinux: sidtab reverse lookup hash table · 66f8e2f0
      Jeff Vander Stoep 提交于
      This replaces the reverse table lookup and reverse cache with a
      hashtable which improves cache-miss reverse-lookup times from
      O(n) to O(1)* and maintains the same performance as a reverse
      cache hit.
      
      This reduces the time needed to add a new sidtab entry from ~500us
      to 5us on a Pixel 3 when there are ~10,000 sidtab entries.
      
      The implementation uses the kernel's generic hashtable API,
      It uses the context's string represtation as the hash source,
      and the kernels generic string hashing algorithm full_name_hash()
      to reduce the string to a 32 bit value.
      
      This change also maintains the improvement introduced in
      commit ee1a84fd ("selinux: overhaul sidtab to fix bug and improve
      performance") which removed the need to keep the current sidtab
      locked during policy reload. It does however introduce periodic
      locking of the target sidtab while converting the hashtable. Sidtab
      entries are never modified or removed, so the context struct stored
      in the sid_to_context tree can also be used for the context_to_sid
      hashtable to reduce memory usage.
      
      This bug was reported by:
      - On the selinux bug tracker.
        BUG: kernel softlockup due to too many SIDs/contexts #37
        https://github.com/SELinuxProject/selinux-kernel/issues/37
      - Jovana Knezevic on Android's bugtracker.
        Bug: 140252993
        "During multi-user performance testing, we create and remove users
        many times. selinux_android_restorecon_pkgdir goes from 1ms to over
        20ms after about 200 user creations and removals. Accumulated over
        ~280 packages, that adds a significant time to user creation,
        making perf benchmarks unreliable."
      
      * Hashtable lookup is only O(1) when n < the number of buckets.
      Signed-off-by: NJeff Vander Stoep <jeffv@google.com>
      Reported-by: NStephen Smalley <sds@tycho.nsa.gov>
      Reported-by: NJovana Knezevic <jovanak@google.com>
      Reviewed-by: NStephen Smalley <sds@tycho.nsa.gov>
      Tested-by: NStephen Smalley <sds@tycho.nsa.gov>
      [PM: subj tweak, removed changelog from patch description]
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      66f8e2f0