Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/security/ipe/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  policy.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
 */


#include <linux/errno.h>
#include <linux/verification.h>

#include "ipe.h"
#include "eval.h"
#include "fs.h"
#include "policy.h"
#include "policy_parser.h"
#include "audit.h"

/* lock for synchronizing writers across ipe policy */
DEFINE_MUTEX(ipe_policy_lock);

/**
 * ver_to_u64() - Convert an internal ipe_policy_version to a u64.
 * @p: Policy to extract the version from.
 *
 * Bits (LSB is index 0):
 * [48,32] -> Major
 * [32,16] -> Minor
 * [16, 0] -> Revision
 *
 * Return: u64 version of the embedded version structure.
 */

static inline u64 ver_to_u64(const struct ipe_policy *const p)
{
 u64 r;

 r = (((u64)p->parsed->version.major) << 32)
   | (((u64)p->parsed->version.minor) << 16)
   | ((u64)(p->parsed->version.rev));

 return r;
}

/**
 * ipe_free_policy() - Deallocate a given IPE policy.
 * @p: Supplies the policy to free.
 *
 * Safe to call on IS_ERR/NULL.
 */

void ipe_free_policy(struct ipe_policy *p)
{
 if (IS_ERR_OR_NULL(p))
  return;

 ipe_del_policyfs_node(p);
 ipe_free_parsed_policy(p->parsed);
 /*
 * p->text is allocated only when p->pkcs7 is not NULL
 * otherwise it points to the plaintext data inside the pkcs7
 */

 if (!p->pkcs7)
  kfree(p->text);
 kfree(p->pkcs7);
 kfree(p);
}

static int set_pkcs7_data(void *ctx, const void *data, size_t len,
     size_t asn1hdrlen __always_unused)
{
 struct ipe_policy *p = ctx;

 p->text = (const char *)data;
 p->textlen = len;

 return 0;
}

/**
 * ipe_update_policy() - parse a new policy and replace old with it.
 * @root: Supplies a pointer to the securityfs inode saved the policy.
 * @text: Supplies a pointer to the plain text policy.
 * @textlen: Supplies the length of @text.
 * @pkcs7: Supplies a pointer to a buffer containing a pkcs7 message.
 * @pkcs7len: Supplies the length of @pkcs7len.
 *
 * @text/@textlen is mutually exclusive with @pkcs7/@pkcs7len - see
 * ipe_new_policy.
 *
 * Context: Requires root->i_rwsem to be held.
 * Return:
 * * %0 - Success
 * * %-ENOENT - Policy was deleted while updating
 * * %-EINVAL - Policy name mismatch
 * * %-ESTALE - Policy version too old
 */

int ipe_update_policy(struct inode *root, const char *text, size_t textlen,
        const char *pkcs7, size_t pkcs7len)
{
 struct ipe_policy *old, *ap, *new = NULL;
 int rc = 0;

 old = (struct ipe_policy *)root->i_private;
 if (!old)
  return -ENOENT;

 new = ipe_new_policy(text, textlen, pkcs7, pkcs7len);
 if (IS_ERR(new))
  return PTR_ERR(new);

 if (strcmp(new->parsed->name, old->parsed->name)) {
  rc = -EINVAL;
  goto err;
 }

 if (ver_to_u64(old) >= ver_to_u64(new)) {
  rc = -ESTALE;
  goto err;
 }

 root->i_private = new;
 swap(new->policyfs, old->policyfs);
 ipe_audit_policy_load(new);

 mutex_lock(&ipe_policy_lock);
 ap = rcu_dereference_protected(ipe_active_policy,
           lockdep_is_held(&ipe_policy_lock));
 if (old == ap) {
  rcu_assign_pointer(ipe_active_policy, new);
  mutex_unlock(&ipe_policy_lock);
  ipe_audit_policy_activation(old, new);
 } else {
  mutex_unlock(&ipe_policy_lock);
 }
 synchronize_rcu();
 ipe_free_policy(old);

 return 0;
err:
 ipe_free_policy(new);
 return rc;
}

/**
 * ipe_new_policy() - Allocate and parse an ipe_policy structure.
 *
 * @text: Supplies a pointer to the plain-text policy to parse.
 * @textlen: Supplies the length of @text.
 * @pkcs7: Supplies a pointer to a pkcs7-signed IPE policy.
 * @pkcs7len: Supplies the length of @pkcs7.
 *
 * @text/@textlen Should be NULL/0 if @pkcs7/@pkcs7len is set.
 *
 * Return:
 * * a pointer to the ipe_policy structure - Success
 * * %-EBADMSG - Policy is invalid
 * * %-ENOMEM - Out of memory (OOM)
 * * %-ERANGE - Policy version number overflow
 * * %-EINVAL - Policy version parsing error
 * * %-ENOKEY - Policy signing key not found
 * * %-EKEYREJECTED - Policy signature verification failed
 */

struct ipe_policy *ipe_new_policy(const char *text, size_t textlen,
      const char *pkcs7, size_t pkcs7len)
{
 struct ipe_policy *new = NULL;
 int rc = 0;

 new = kzalloc(sizeof(*new), GFP_KERNEL);
 if (!new)
  return ERR_PTR(-ENOMEM);

 if (!text) {
  new->pkcs7len = pkcs7len;
  new->pkcs7 = kmemdup(pkcs7, pkcs7len, GFP_KERNEL);
  if (!new->pkcs7) {
   rc = -ENOMEM;
   goto err;
  }

  rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len,
#ifdef CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING
         VERIFY_USE_SECONDARY_KEYRING,
#else
         NULL,
#endif
         VERIFYING_UNSPECIFIED_SIGNATURE,
         set_pkcs7_data, new);
#ifdef CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING
  if (rc == -ENOKEY || rc == -EKEYREJECTED)
   rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len,
          VERIFY_USE_PLATFORM_KEYRING,
          VERIFYING_UNSPECIFIED_SIGNATURE,
          set_pkcs7_data, new);
#endif
  if (rc)
   goto err;
 } else {
  new->textlen = textlen;
  new->text = kstrdup(text, GFP_KERNEL);
  if (!new->text) {
   rc = -ENOMEM;
   goto err;
  }
 }

 rc = ipe_parse_policy(new);
 if (rc)
  goto err;

 return new;
err:
 ipe_free_policy(new);
 return ERR_PTR(rc);
}

/**
 * ipe_set_active_pol() - Make @p the active policy.
 * @p: Supplies a pointer to the policy to make active.
 *
 * Context: Requires root->i_rwsem, which i_private has the policy, to be held.
 * Return:
 * * %0 - Success
 * * %-EINVAL - New active policy version is invalid
 */

int ipe_set_active_pol(const struct ipe_policy *p)
{
 struct ipe_policy *ap = NULL;

 mutex_lock(&ipe_policy_lock);

 ap = rcu_dereference_protected(ipe_active_policy,
           lockdep_is_held(&ipe_policy_lock));
 if (ap == p) {
  mutex_unlock(&ipe_policy_lock);
  return 0;
 }
 if (ap && ver_to_u64(ap) > ver_to_u64(p)) {
  mutex_unlock(&ipe_policy_lock);
  return -EINVAL;
 }

 rcu_assign_pointer(ipe_active_policy, p);
 ipe_audit_policy_activation(ap, p);
 mutex_unlock(&ipe_policy_lock);

 return 0;
}

Messung V0.5
C=90 H=92 G=90

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.