All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Smalley <stephen.smalley.work@gmail.com>
To: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>,
	Casey Schaufler <casey@schaufler-ca.com>,
	James Morris <jmorris@namei.org>,
	linux-integrity@vger.kernel.org,
	SElinux list <selinux@vger.kernel.org>,
	LSM List <linux-security-module@vger.kernel.org>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3 4/5] LSM: Define SELinux function to measure security state
Date: Mon, 20 Jul 2020 10:31:34 -0400	[thread overview]
Message-ID: <CAEjxPJ7xQtZToF4d2w_o8SXFKG9kPZaWTWTFqyC-7GwBWnQa0A@mail.gmail.com> (raw)
In-Reply-To: <20200717222819.26198-5-nramas@linux.microsoft.com>

On Fri, Jul 17, 2020 at 6:28 PM Lakshmi Ramasubramanian
<nramas@linux.microsoft.com> wrote:
>
> SELinux configuration and policy are some of the critical data for this
> security module that needs to be measured. To enable this measurement
> SELinux needs to implement the interface function,
> security_measure_data(), that the LSM can call.
>
> Define the security_measure_data() function in SELinux to measure SELinux
> configuration and policy. Call this function to measure SELinux data
> when there is a change in the security module's state.
>
> Sample measurement of SELinux state and hash of the policy:
>
> 10 e32e...5ac3 ima-buf sha256:86e8...4594 selinux-state 656e61626c65643d313b656e666f7263696e673d303b636865636b72657170726f743d313b6e6574706565723d313b6f70656e7065726d3d313b657874736f636b636c6173733d313b616c776179736e6574776f726b3d303b6367726f75707365636c6162656c3d313b6e6e706e6f737569647472616e736974696f6e3d313b67656e66737365636c6162656c73796d6c696e6b3d303b
> 10 f4a7...9408 ima-buf sha256:4941...68fc selinux-policy-hash 8d1d...1834
>
> To verify the measurement check the following:
>
> Execute the following command to extract the measured data
> from the IMA log for SELinux configuration (selinux-state).
>
>   cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep -m 1 "selinux-state" | cut -d' ' -f 6 | xxd -r -p
>
> The output should be the list of key-value pairs. For example,
>  enabled=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 measured data with the current SELinux state:
>
>  => enabled should be set to 1 if /sys/fs/selinux folder exists,
>     0 otherwise
>
> For other entries, compare the integer value in the files
>  => /sys/fs/selinux/enforce
>  => /sys/fs/selinux/checkreqprot
> And, each of the policy capabilities files under
>  => /sys/fs/selinux/policy_capabilities
>
> The data for selinux-policy-hash is the SHA256 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
>
>   cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep -m 1 "selinux-policy-hash" | cut -d' ' -f 6
>
> Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
> Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
> ---

> diff --git a/security/selinux/measure.c b/security/selinux/measure.c
> new file mode 100644
> index 000000000000..659011637ae7
> --- /dev/null
> +++ b/security/selinux/measure.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Measure SELinux state using IMA subsystem.
> + */
> +#include <linux/ima.h>
> +#include "security.h"
> +
> +/* Pre-allocated buffer used for measuring state */
> +static char *selinux_state_string;
> +static size_t selinux_state_string_len;
> +static char *str_format = "%s=%d;";
> +static int selinux_state_count;
> +
> +void __init selinux_init_measurement(void)
> +{
> +       int i;
> +
> +       /*
> +        * enabled
> +        * enforcing
> +        * checkreqport

checkreqprot (spelling)

What about initialized?  Or do you consider that to be implicitly
true/1 else we wouldn't be taking a measurement?  Only caveat there is
that it provides one more means of disabling measurements (at the same
time as disabling enforcement) by setting it to false/0 via kernel
write flaw.

> +        * All policy capability flags
> +        */
> +       selinux_state_count = 3 + __POLICYDB_CAPABILITY_MAX;
> +
> +       selinux_state_string_len = snprintf(NULL, 0, str_format,
> +                                           "enabled", 0);
> +       selinux_state_string_len += snprintf(NULL, 0, str_format,
> +                                            "enforcing", 0);
> +       selinux_state_string_len += snprintf(NULL, 0, str_format,
> +                                            "checkreqprot", 0);
> +       for (i = 3; i < selinux_state_count; i++) {
> +               selinux_state_string_len +=
> +                       snprintf(NULL, 0, str_format,
> +                                selinux_policycap_names[i-3], 0);
> +       }

What's the benefit of this pattern versus just making the loop go from
0 to __POLICYDB_CAPABILITY_MAX and using selinux_policycap_names[i]?

> +void selinux_measure_state(struct selinux_state *selinux_state)
> +{
> +       void *policy = NULL;
> +       void *policy_hash = NULL;
> +       size_t curr, buflen;
> +       int i, policy_hash_len, rc = 0;
> +
> +       if (!selinux_initialized(selinux_state)) {
> +               pr_warn("%s: SELinux not yet initialized.\n", __func__);
> +               return;
> +       }

We could measure the global state variables before full SELinux
initialization (i.e. policy load).
Only the policy hash depends on having loaded the policy.

> +
> +       if (!selinux_state_string) {
> +               pr_warn("%s: Buffer for state not allocated.\n", __func__);
> +               return;
> +       }
> +
> +       curr = snprintf(selinux_state_string, selinux_state_string_len,
> +                       str_format, "enabled",
> +                       !selinux_disabled(selinux_state));
> +       curr += snprintf((selinux_state_string + curr),
> +                        (selinux_state_string_len - curr),
> +                        str_format, "enforcing",
> +                        enforcing_enabled(selinux_state));
> +       curr += snprintf((selinux_state_string + curr),
> +                        (selinux_state_string_len - curr),
> +                        str_format, "checkreqprot",
> +                        selinux_checkreqprot(selinux_state));
> +
> +       for (i = 3; i < selinux_state_count; i++) {
> +               curr += snprintf((selinux_state_string + curr),
> +                                (selinux_state_string_len - curr),
> +                                str_format,
> +                                selinux_policycap_names[i - 3],
> +                                selinux_state->policycap[i - 3]);
> +       }

Same question here as for the previous loop; seems cleaner to go from
0 to __POLICYDB_CAPABILITY_MAX and use [i].

What public git tree / branch would you recommend trying to use your
patches against?  Didn't seem to apply to any of the obvious ones.

  parent reply	other threads:[~2020-07-20 14:31 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-17 22:28 [PATCH v3 0/5] LSM: Measure security module state Lakshmi Ramasubramanian
2020-07-17 22:28 ` [PATCH v3 1/5] IMA: Add LSM_STATE func to measure LSM data Lakshmi Ramasubramanian
2020-07-17 22:28 ` [PATCH v3 2/5] IMA: Define an IMA hook " Lakshmi Ramasubramanian
2020-07-17 22:28 ` [PATCH v3 3/5] LSM: Add security_measure_data in lsm_info struct Lakshmi Ramasubramanian
2020-07-17 22:28 ` [PATCH v3 4/5] LSM: Define SELinux function to measure security state Lakshmi Ramasubramanian
2020-07-18  3:14   ` kernel test robot
2020-07-18  3:14     ` kernel test robot
2020-07-20  2:04     ` Lakshmi Ramasubramanian
2020-07-18  3:38   ` kernel test robot
2020-07-18  3:38     ` kernel test robot
2020-07-18 15:31   ` kernel test robot
2020-07-18 15:31     ` kernel test robot
2020-07-18 15:31   ` [RFC PATCH] LSM: security_read_selinux_policy() can be static kernel test robot
2020-07-18 15:31     ` kernel test robot
2020-07-20 14:31   ` Stephen Smalley [this message]
2020-07-20 15:17     ` [PATCH v3 4/5] LSM: Define SELinux function to measure security state Lakshmi Ramasubramanian
2020-07-20 17:06       ` Stephen Smalley
2020-07-20 17:26         ` Mimi Zohar
2020-07-20 17:34         ` Lakshmi Ramasubramanian
2020-07-20 17:40           ` Stephen Smalley
2020-07-20 17:49             ` Stephen Smalley
2020-07-20 18:27               ` Lakshmi Ramasubramanian
2020-07-20 18:44                 ` Stephen Smalley
2020-07-20 18:59                   ` Lakshmi Ramasubramanian
2020-07-17 22:28 ` [PATCH v3 5/5] LSM: Define workqueue for measuring security module state Lakshmi Ramasubramanian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAEjxPJ7xQtZToF4d2w_o8SXFKG9kPZaWTWTFqyC-7GwBWnQa0A@mail.gmail.com \
    --to=stephen.smalley.work@gmail.com \
    --cc=casey@schaufler-ca.com \
    --cc=jmorris@namei.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=nramas@linux.microsoft.com \
    --cc=selinux@vger.kernel.org \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.