~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/ipe/policy.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /security/ipe/policy.c (Architecture mips) and /security/ipe/policy.c (Architecture sparc)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2 /*                                                  2 /*
  3  * Copyright (C) 2020-2024 Microsoft Corporati      3  * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
  4  */                                                 4  */
  5                                                     5 
  6 #include <linux/errno.h>                            6 #include <linux/errno.h>
  7 #include <linux/verification.h>                     7 #include <linux/verification.h>
  8                                                     8 
  9 #include "ipe.h"                                    9 #include "ipe.h"
 10 #include "eval.h"                                  10 #include "eval.h"
 11 #include "fs.h"                                    11 #include "fs.h"
 12 #include "policy.h"                                12 #include "policy.h"
 13 #include "policy_parser.h"                         13 #include "policy_parser.h"
 14 #include "audit.h"                                 14 #include "audit.h"
 15                                                    15 
 16 /* lock for synchronizing writers across ipe p     16 /* lock for synchronizing writers across ipe policy */
 17 DEFINE_MUTEX(ipe_policy_lock);                     17 DEFINE_MUTEX(ipe_policy_lock);
 18                                                    18 
 19 /**                                                19 /**
 20  * ver_to_u64() - Convert an internal ipe_poli     20  * ver_to_u64() - Convert an internal ipe_policy_version to a u64.
 21  * @p: Policy to extract the version from.         21  * @p: Policy to extract the version from.
 22  *                                                 22  *
 23  * Bits (LSB is index 0):                          23  * Bits (LSB is index 0):
 24  *      [48,32] -> Major                           24  *      [48,32] -> Major
 25  *      [32,16] -> Minor                           25  *      [32,16] -> Minor
 26  *      [16, 0] -> Revision                        26  *      [16, 0] -> Revision
 27  *                                                 27  *
 28  * Return: u64 version of the embedded version     28  * Return: u64 version of the embedded version structure.
 29  */                                                29  */
 30 static inline u64 ver_to_u64(const struct ipe_     30 static inline u64 ver_to_u64(const struct ipe_policy *const p)
 31 {                                                  31 {
 32         u64 r;                                     32         u64 r;
 33                                                    33 
 34         r = (((u64)p->parsed->version.major) <     34         r = (((u64)p->parsed->version.major) << 32)
 35           | (((u64)p->parsed->version.minor) <     35           | (((u64)p->parsed->version.minor) << 16)
 36           | ((u64)(p->parsed->version.rev));       36           | ((u64)(p->parsed->version.rev));
 37                                                    37 
 38         return r;                                  38         return r;
 39 }                                                  39 }
 40                                                    40 
 41 /**                                                41 /**
 42  * ipe_free_policy() - Deallocate a given IPE      42  * ipe_free_policy() - Deallocate a given IPE policy.
 43  * @p: Supplies the policy to free.                43  * @p: Supplies the policy to free.
 44  *                                                 44  *
 45  * Safe to call on IS_ERR/NULL.                    45  * Safe to call on IS_ERR/NULL.
 46  */                                                46  */
 47 void ipe_free_policy(struct ipe_policy *p)         47 void ipe_free_policy(struct ipe_policy *p)
 48 {                                                  48 {
 49         if (IS_ERR_OR_NULL(p))                     49         if (IS_ERR_OR_NULL(p))
 50                 return;                            50                 return;
 51                                                    51 
 52         ipe_del_policyfs_node(p);                  52         ipe_del_policyfs_node(p);
 53         ipe_free_parsed_policy(p->parsed);         53         ipe_free_parsed_policy(p->parsed);
 54         /*                                         54         /*
 55          * p->text is allocated only when p->p     55          * p->text is allocated only when p->pkcs7 is not NULL
 56          * otherwise it points to the plaintex     56          * otherwise it points to the plaintext data inside the pkcs7
 57          */                                        57          */
 58         if (!p->pkcs7)                             58         if (!p->pkcs7)
 59                 kfree(p->text);                    59                 kfree(p->text);
 60         kfree(p->pkcs7);                           60         kfree(p->pkcs7);
 61         kfree(p);                                  61         kfree(p);
 62 }                                                  62 }
 63                                                    63 
 64 static int set_pkcs7_data(void *ctx, const voi     64 static int set_pkcs7_data(void *ctx, const void *data, size_t len,
 65                           size_t asn1hdrlen __     65                           size_t asn1hdrlen __always_unused)
 66 {                                                  66 {
 67         struct ipe_policy *p = ctx;                67         struct ipe_policy *p = ctx;
 68                                                    68 
 69         p->text = (const char *)data;              69         p->text = (const char *)data;
 70         p->textlen = len;                          70         p->textlen = len;
 71                                                    71 
 72         return 0;                                  72         return 0;
 73 }                                                  73 }
 74                                                    74 
 75 /**                                                75 /**
 76  * ipe_update_policy() - parse a new policy an     76  * ipe_update_policy() - parse a new policy and replace old with it.
 77  * @root: Supplies a pointer to the securityfs     77  * @root: Supplies a pointer to the securityfs inode saved the policy.
 78  * @text: Supplies a pointer to the plain text     78  * @text: Supplies a pointer to the plain text policy.
 79  * @textlen: Supplies the length of @text.         79  * @textlen: Supplies the length of @text.
 80  * @pkcs7: Supplies a pointer to a buffer cont     80  * @pkcs7: Supplies a pointer to a buffer containing a pkcs7 message.
 81  * @pkcs7len: Supplies the length of @pkcs7len     81  * @pkcs7len: Supplies the length of @pkcs7len.
 82  *                                                 82  *
 83  * @text/@textlen is mutually exclusive with @     83  * @text/@textlen is mutually exclusive with @pkcs7/@pkcs7len - see
 84  * ipe_new_policy.                                 84  * ipe_new_policy.
 85  *                                                 85  *
 86  * Context: Requires root->i_rwsem to be held.     86  * Context: Requires root->i_rwsem to be held.
 87  * Return: %0 on success. If an error occurs,      87  * Return: %0 on success. If an error occurs, the function will return
 88  * the -errno.                                     88  * the -errno.
 89  */                                                89  */
 90 int ipe_update_policy(struct inode *root, cons     90 int ipe_update_policy(struct inode *root, const char *text, size_t textlen,
 91                       const char *pkcs7, size_     91                       const char *pkcs7, size_t pkcs7len)
 92 {                                                  92 {
 93         struct ipe_policy *old, *ap, *new = NU     93         struct ipe_policy *old, *ap, *new = NULL;
 94         int rc = 0;                                94         int rc = 0;
 95                                                    95 
 96         old = (struct ipe_policy *)root->i_pri     96         old = (struct ipe_policy *)root->i_private;
 97         if (!old)                                  97         if (!old)
 98                 return -ENOENT;                    98                 return -ENOENT;
 99                                                    99 
100         new = ipe_new_policy(text, textlen, pk    100         new = ipe_new_policy(text, textlen, pkcs7, pkcs7len);
101         if (IS_ERR(new))                          101         if (IS_ERR(new))
102                 return PTR_ERR(new);              102                 return PTR_ERR(new);
103                                                   103 
104         if (strcmp(new->parsed->name, old->par    104         if (strcmp(new->parsed->name, old->parsed->name)) {
105                 rc = -EINVAL;                     105                 rc = -EINVAL;
106                 goto err;                         106                 goto err;
107         }                                         107         }
108                                                   108 
109         if (ver_to_u64(old) >= ver_to_u64(new)    109         if (ver_to_u64(old) >= ver_to_u64(new)) {
110                 rc = -ESTALE;                     110                 rc = -ESTALE;
111                 goto err;                         111                 goto err;
112         }                                         112         }
113                                                   113 
114         root->i_private = new;                    114         root->i_private = new;
115         swap(new->policyfs, old->policyfs);       115         swap(new->policyfs, old->policyfs);
116         ipe_audit_policy_load(new);               116         ipe_audit_policy_load(new);
117                                                   117 
118         mutex_lock(&ipe_policy_lock);             118         mutex_lock(&ipe_policy_lock);
119         ap = rcu_dereference_protected(ipe_act    119         ap = rcu_dereference_protected(ipe_active_policy,
120                                        lockdep    120                                        lockdep_is_held(&ipe_policy_lock));
121         if (old == ap) {                          121         if (old == ap) {
122                 rcu_assign_pointer(ipe_active_    122                 rcu_assign_pointer(ipe_active_policy, new);
123                 mutex_unlock(&ipe_policy_lock)    123                 mutex_unlock(&ipe_policy_lock);
124                 ipe_audit_policy_activation(ol    124                 ipe_audit_policy_activation(old, new);
125         } else {                                  125         } else {
126                 mutex_unlock(&ipe_policy_lock)    126                 mutex_unlock(&ipe_policy_lock);
127         }                                         127         }
128         synchronize_rcu();                        128         synchronize_rcu();
129         ipe_free_policy(old);                     129         ipe_free_policy(old);
130                                                   130 
131         return 0;                                 131         return 0;
132 err:                                              132 err:
133         ipe_free_policy(new);                     133         ipe_free_policy(new);
134         return rc;                                134         return rc;
135 }                                                 135 }
136                                                   136 
137 /**                                               137 /**
138  * ipe_new_policy() - Allocate and parse an ip    138  * ipe_new_policy() - Allocate and parse an ipe_policy structure.
139  *                                                139  *
140  * @text: Supplies a pointer to the plain-text    140  * @text: Supplies a pointer to the plain-text policy to parse.
141  * @textlen: Supplies the length of @text.        141  * @textlen: Supplies the length of @text.
142  * @pkcs7: Supplies a pointer to a pkcs7-signe    142  * @pkcs7: Supplies a pointer to a pkcs7-signed IPE policy.
143  * @pkcs7len: Supplies the length of @pkcs7.      143  * @pkcs7len: Supplies the length of @pkcs7.
144  *                                                144  *
145  * @text/@textlen Should be NULL/0 if @pkcs7/@    145  * @text/@textlen Should be NULL/0 if @pkcs7/@pkcs7len is set.
146  *                                                146  *
147  * Return:                                        147  * Return:
148  * * a pointer to the ipe_policy structure        148  * * a pointer to the ipe_policy structure      - Success
149  * * %-EBADMSG                                    149  * * %-EBADMSG                                  - Policy is invalid
150  * * %-ENOMEM                                     150  * * %-ENOMEM                                   - Out of memory (OOM)
151  * * %-ERANGE                                     151  * * %-ERANGE                                   - Policy version number overflow
152  * * %-EINVAL                                     152  * * %-EINVAL                                   - Policy version parsing error
153  */                                               153  */
154 struct ipe_policy *ipe_new_policy(const char *    154 struct ipe_policy *ipe_new_policy(const char *text, size_t textlen,
155                                   const char *    155                                   const char *pkcs7, size_t pkcs7len)
156 {                                                 156 {
157         struct ipe_policy *new = NULL;            157         struct ipe_policy *new = NULL;
158         int rc = 0;                               158         int rc = 0;
159                                                   159 
160         new = kzalloc(sizeof(*new), GFP_KERNEL    160         new = kzalloc(sizeof(*new), GFP_KERNEL);
161         if (!new)                                 161         if (!new)
162                 return ERR_PTR(-ENOMEM);          162                 return ERR_PTR(-ENOMEM);
163                                                   163 
164         if (!text) {                              164         if (!text) {
165                 new->pkcs7len = pkcs7len;         165                 new->pkcs7len = pkcs7len;
166                 new->pkcs7 = kmemdup(pkcs7, pk    166                 new->pkcs7 = kmemdup(pkcs7, pkcs7len, GFP_KERNEL);
167                 if (!new->pkcs7) {                167                 if (!new->pkcs7) {
168                         rc = -ENOMEM;             168                         rc = -ENOMEM;
169                         goto err;                 169                         goto err;
170                 }                                 170                 }
171                                                   171 
172                 rc = verify_pkcs7_signature(NU    172                 rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len,
173 #ifdef CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING    173 #ifdef CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING
174                                             VE    174                                             VERIFY_USE_SECONDARY_KEYRING,
175 #else                                             175 #else
176                                             NU    176                                             NULL,
177 #endif                                            177 #endif
178                                             VE    178                                             VERIFYING_UNSPECIFIED_SIGNATURE,
179                                             se    179                                             set_pkcs7_data, new);
180 #ifdef CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING     180 #ifdef CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING
181                 if (rc == -ENOKEY || rc == -EK    181                 if (rc == -ENOKEY || rc == -EKEYREJECTED)
182                         rc = verify_pkcs7_sign    182                         rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len,
183                                                   183                                                     VERIFY_USE_PLATFORM_KEYRING,
184                                                   184                                                     VERIFYING_UNSPECIFIED_SIGNATURE,
185                                                   185                                                     set_pkcs7_data, new);
186 #endif                                            186 #endif
187                 if (rc)                           187                 if (rc)
188                         goto err;                 188                         goto err;
189         } else {                                  189         } else {
190                 new->textlen = textlen;           190                 new->textlen = textlen;
191                 new->text = kstrdup(text, GFP_    191                 new->text = kstrdup(text, GFP_KERNEL);
192                 if (!new->text) {                 192                 if (!new->text) {
193                         rc = -ENOMEM;             193                         rc = -ENOMEM;
194                         goto err;                 194                         goto err;
195                 }                                 195                 }
196         }                                         196         }
197                                                   197 
198         rc = ipe_parse_policy(new);               198         rc = ipe_parse_policy(new);
199         if (rc)                                   199         if (rc)
200                 goto err;                         200                 goto err;
201                                                   201 
202         return new;                               202         return new;
203 err:                                              203 err:
204         ipe_free_policy(new);                     204         ipe_free_policy(new);
205         return ERR_PTR(rc);                       205         return ERR_PTR(rc);
206 }                                                 206 }
207                                                   207 
208 /**                                               208 /**
209  * ipe_set_active_pol() - Make @p the active p    209  * ipe_set_active_pol() - Make @p the active policy.
210  * @p: Supplies a pointer to the policy to mak    210  * @p: Supplies a pointer to the policy to make active.
211  *                                                211  *
212  * Context: Requires root->i_rwsem, which i_pr    212  * Context: Requires root->i_rwsem, which i_private has the policy, to be held.
213  * Return:                                        213  * Return:
214  * * %0 - Success                                 214  * * %0 - Success
215  * * %-EINVAL   - New active policy version is    215  * * %-EINVAL   - New active policy version is invalid
216  */                                               216  */
217 int ipe_set_active_pol(const struct ipe_policy    217 int ipe_set_active_pol(const struct ipe_policy *p)
218 {                                                 218 {
219         struct ipe_policy *ap = NULL;             219         struct ipe_policy *ap = NULL;
220                                                   220 
221         mutex_lock(&ipe_policy_lock);             221         mutex_lock(&ipe_policy_lock);
222                                                   222 
223         ap = rcu_dereference_protected(ipe_act    223         ap = rcu_dereference_protected(ipe_active_policy,
224                                        lockdep    224                                        lockdep_is_held(&ipe_policy_lock));
225         if (ap == p) {                            225         if (ap == p) {
226                 mutex_unlock(&ipe_policy_lock)    226                 mutex_unlock(&ipe_policy_lock);
227                 return 0;                         227                 return 0;
228         }                                         228         }
229         if (ap && ver_to_u64(ap) > ver_to_u64(    229         if (ap && ver_to_u64(ap) > ver_to_u64(p)) {
230                 mutex_unlock(&ipe_policy_lock)    230                 mutex_unlock(&ipe_policy_lock);
231                 return -EINVAL;                   231                 return -EINVAL;
232         }                                         232         }
233                                                   233 
234         rcu_assign_pointer(ipe_active_policy,     234         rcu_assign_pointer(ipe_active_policy, p);
235         ipe_audit_policy_activation(ap, p);       235         ipe_audit_policy_activation(ap, p);
236         mutex_unlock(&ipe_policy_lock);           236         mutex_unlock(&ipe_policy_lock);
237                                                   237 
238         return 0;                                 238         return 0;
239 }                                                 239 }
240                                                   240 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php