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

TOMOYO Linux Cross Reference
Linux/security/ipe/policy_parser.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_parser.c (Architecture mips) and /security/ipe/policy_parser.c (Architecture i386)


  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/err.h>                              6 #include <linux/err.h>
  7 #include <linux/slab.h>                             7 #include <linux/slab.h>
  8 #include <linux/parser.h>                           8 #include <linux/parser.h>
  9 #include <linux/types.h>                            9 #include <linux/types.h>
 10 #include <linux/ctype.h>                           10 #include <linux/ctype.h>
 11                                                    11 
 12 #include "policy.h"                                12 #include "policy.h"
 13 #include "policy_parser.h"                         13 #include "policy_parser.h"
 14 #include "digest.h"                                14 #include "digest.h"
 15                                                    15 
 16 #define START_COMMENT   '#'                        16 #define START_COMMENT   '#'
 17 #define IPE_POLICY_DELIM " \t"                     17 #define IPE_POLICY_DELIM " \t"
 18 #define IPE_LINE_DELIM "\n\r"                      18 #define IPE_LINE_DELIM "\n\r"
 19                                                    19 
 20 /**                                                20 /**
 21  * new_parsed_policy() - Allocate and initiali     21  * new_parsed_policy() - Allocate and initialize a parsed policy.
 22  *                                                 22  *
 23  * Return:                                         23  * Return:
 24  * * a pointer to the ipe_parsed_policy struct     24  * * a pointer to the ipe_parsed_policy structure       - Success
 25  * * %-ENOMEM                                      25  * * %-ENOMEM                                           - Out of memory (OOM)
 26  */                                                26  */
 27 static struct ipe_parsed_policy *new_parsed_po     27 static struct ipe_parsed_policy *new_parsed_policy(void)
 28 {                                                  28 {
 29         struct ipe_parsed_policy *p = NULL;        29         struct ipe_parsed_policy *p = NULL;
 30         struct ipe_op_table *t = NULL;             30         struct ipe_op_table *t = NULL;
 31         size_t i = 0;                              31         size_t i = 0;
 32                                                    32 
 33         p = kzalloc(sizeof(*p), GFP_KERNEL);       33         p = kzalloc(sizeof(*p), GFP_KERNEL);
 34         if (!p)                                    34         if (!p)
 35                 return ERR_PTR(-ENOMEM);           35                 return ERR_PTR(-ENOMEM);
 36                                                    36 
 37         p->global_default_action = IPE_ACTION_     37         p->global_default_action = IPE_ACTION_INVALID;
 38                                                    38 
 39         for (i = 0; i < ARRAY_SIZE(p->rules);      39         for (i = 0; i < ARRAY_SIZE(p->rules); ++i) {
 40                 t = &p->rules[i];                  40                 t = &p->rules[i];
 41                                                    41 
 42                 t->default_action = IPE_ACTION     42                 t->default_action = IPE_ACTION_INVALID;
 43                 INIT_LIST_HEAD(&t->rules);         43                 INIT_LIST_HEAD(&t->rules);
 44         }                                          44         }
 45                                                    45 
 46         return p;                                  46         return p;
 47 }                                                  47 }
 48                                                    48 
 49 /**                                                49 /**
 50  * remove_comment() - Truncate all chars follo     50  * remove_comment() - Truncate all chars following START_COMMENT in a string.
 51  *                                                 51  *
 52  * @line: Supplies a policy line string for pr     52  * @line: Supplies a policy line string for preprocessing.
 53  */                                                53  */
 54 static void remove_comment(char *line)             54 static void remove_comment(char *line)
 55 {                                                  55 {
 56         line = strchr(line, START_COMMENT);        56         line = strchr(line, START_COMMENT);
 57                                                    57 
 58         if (line)                                  58         if (line)
 59                 *line = '\0';                      59                 *line = '\0';
 60 }                                                  60 }
 61                                                    61 
 62 /**                                                62 /**
 63  * remove_trailing_spaces() - Truncate all tra     63  * remove_trailing_spaces() - Truncate all trailing spaces in a string.
 64  *                                                 64  *
 65  * @line: Supplies a policy line string for pr     65  * @line: Supplies a policy line string for preprocessing.
 66  *                                                 66  *
 67  * Return: The length of truncated string.         67  * Return: The length of truncated string.
 68  */                                                68  */
 69 static size_t remove_trailing_spaces(char *lin     69 static size_t remove_trailing_spaces(char *line)
 70 {                                                  70 {
 71         size_t i = 0;                              71         size_t i = 0;
 72                                                    72 
 73         i = strlen(line);                          73         i = strlen(line);
 74         while (i > 0 && isspace(line[i - 1]))      74         while (i > 0 && isspace(line[i - 1]))
 75                 i--;                               75                 i--;
 76                                                    76 
 77         line[i] = '\0';                            77         line[i] = '\0';
 78                                                    78 
 79         return i;                                  79         return i;
 80 }                                                  80 }
 81                                                    81 
 82 /**                                                82 /**
 83  * parse_version() - Parse policy version.         83  * parse_version() - Parse policy version.
 84  * @ver: Supplies a version string to be parse     84  * @ver: Supplies a version string to be parsed.
 85  * @p: Supplies the partial parsed policy.         85  * @p: Supplies the partial parsed policy.
 86  *                                                 86  *
 87  * Return:                                         87  * Return:
 88  * * %0         - Success                          88  * * %0         - Success
 89  * * %-EBADMSG  - Version string is invalid        89  * * %-EBADMSG  - Version string is invalid
 90  * * %-ERANGE   - Version number overflow          90  * * %-ERANGE   - Version number overflow
 91  * * %-EINVAL   - Parsing error                    91  * * %-EINVAL   - Parsing error
 92  */                                                92  */
 93 static int parse_version(char *ver, struct ipe     93 static int parse_version(char *ver, struct ipe_parsed_policy *p)
 94 {                                                  94 {
 95         u16 *const cv[] = { &p->version.major,     95         u16 *const cv[] = { &p->version.major, &p->version.minor, &p->version.rev };
 96         size_t sep_count = 0;                      96         size_t sep_count = 0;
 97         char *token;                               97         char *token;
 98         int rc = 0;                                98         int rc = 0;
 99                                                    99 
100         while ((token = strsep(&ver, ".")) !=     100         while ((token = strsep(&ver, ".")) != NULL) {
101                 /* prevent overflow */            101                 /* prevent overflow */
102                 if (sep_count >= ARRAY_SIZE(cv    102                 if (sep_count >= ARRAY_SIZE(cv))
103                         return -EBADMSG;          103                         return -EBADMSG;
104                                                   104 
105                 rc = kstrtou16(token, 10, cv[s    105                 rc = kstrtou16(token, 10, cv[sep_count]);
106                 if (rc)                           106                 if (rc)
107                         return rc;                107                         return rc;
108                                                   108 
109                 ++sep_count;                      109                 ++sep_count;
110         }                                         110         }
111                                                   111 
112         /* prevent underflow */                   112         /* prevent underflow */
113         if (sep_count != ARRAY_SIZE(cv))          113         if (sep_count != ARRAY_SIZE(cv))
114                 return -EBADMSG;                  114                 return -EBADMSG;
115                                                   115 
116         return 0;                                 116         return 0;
117 }                                                 117 }
118                                                   118 
119 enum header_opt {                                 119 enum header_opt {
120         IPE_HEADER_POLICY_NAME = 0,               120         IPE_HEADER_POLICY_NAME = 0,
121         IPE_HEADER_POLICY_VERSION,                121         IPE_HEADER_POLICY_VERSION,
122         __IPE_HEADER_MAX                          122         __IPE_HEADER_MAX
123 };                                                123 };
124                                                   124 
125 static const match_table_t header_tokens = {      125 static const match_table_t header_tokens = {
126         {IPE_HEADER_POLICY_NAME,        "polic    126         {IPE_HEADER_POLICY_NAME,        "policy_name=%s"},
127         {IPE_HEADER_POLICY_VERSION,     "polic    127         {IPE_HEADER_POLICY_VERSION,     "policy_version=%s"},
128         {__IPE_HEADER_MAX,              NULL}     128         {__IPE_HEADER_MAX,              NULL}
129 };                                                129 };
130                                                   130 
131 /**                                               131 /**
132  * parse_header() - Parse policy header inform    132  * parse_header() - Parse policy header information.
133  * @line: Supplies header line to be parsed.      133  * @line: Supplies header line to be parsed.
134  * @p: Supplies the partial parsed policy.        134  * @p: Supplies the partial parsed policy.
135  *                                                135  *
136  * Return:                                        136  * Return:
137  * * %0         - Success                         137  * * %0         - Success
138  * * %-EBADMSG  - Header string is invalid        138  * * %-EBADMSG  - Header string is invalid
139  * * %-ENOMEM   - Out of memory (OOM)             139  * * %-ENOMEM   - Out of memory (OOM)
140  * * %-ERANGE   - Version number overflow         140  * * %-ERANGE   - Version number overflow
141  * * %-EINVAL   - Version parsing error           141  * * %-EINVAL   - Version parsing error
142  */                                               142  */
143 static int parse_header(char *line, struct ipe    143 static int parse_header(char *line, struct ipe_parsed_policy *p)
144 {                                                 144 {
145         substring_t args[MAX_OPT_ARGS];           145         substring_t args[MAX_OPT_ARGS];
146         char *t, *ver = NULL;                     146         char *t, *ver = NULL;
147         size_t idx = 0;                           147         size_t idx = 0;
148         int rc = 0;                               148         int rc = 0;
149                                                   149 
150         while ((t = strsep(&line, IPE_POLICY_D    150         while ((t = strsep(&line, IPE_POLICY_DELIM)) != NULL) {
151                 int token;                        151                 int token;
152                                                   152 
153                 if (*t == '\0')                   153                 if (*t == '\0')
154                         continue;                 154                         continue;
155                 if (idx >= __IPE_HEADER_MAX) {    155                 if (idx >= __IPE_HEADER_MAX) {
156                         rc = -EBADMSG;            156                         rc = -EBADMSG;
157                         goto out;                 157                         goto out;
158                 }                                 158                 }
159                                                   159 
160                 token = match_token(t, header_    160                 token = match_token(t, header_tokens, args);
161                 if (token != idx) {               161                 if (token != idx) {
162                         rc = -EBADMSG;            162                         rc = -EBADMSG;
163                         goto out;                 163                         goto out;
164                 }                                 164                 }
165                                                   165 
166                 switch (token) {                  166                 switch (token) {
167                 case IPE_HEADER_POLICY_NAME:      167                 case IPE_HEADER_POLICY_NAME:
168                         p->name = match_strdup    168                         p->name = match_strdup(&args[0]);
169                         if (!p->name)             169                         if (!p->name)
170                                 rc = -ENOMEM;     170                                 rc = -ENOMEM;
171                         break;                    171                         break;
172                 case IPE_HEADER_POLICY_VERSION    172                 case IPE_HEADER_POLICY_VERSION:
173                         ver = match_strdup(&ar    173                         ver = match_strdup(&args[0]);
174                         if (!ver) {               174                         if (!ver) {
175                                 rc = -ENOMEM;     175                                 rc = -ENOMEM;
176                                 break;            176                                 break;
177                         }                         177                         }
178                         rc = parse_version(ver    178                         rc = parse_version(ver, p);
179                         break;                    179                         break;
180                 default:                          180                 default:
181                         rc = -EBADMSG;            181                         rc = -EBADMSG;
182                 }                                 182                 }
183                 if (rc)                           183                 if (rc)
184                         goto out;                 184                         goto out;
185                 ++idx;                            185                 ++idx;
186         }                                         186         }
187                                                   187 
188         if (idx != __IPE_HEADER_MAX)              188         if (idx != __IPE_HEADER_MAX)
189                 rc = -EBADMSG;                    189                 rc = -EBADMSG;
190                                                   190 
191 out:                                              191 out:
192         kfree(ver);                               192         kfree(ver);
193         return rc;                                193         return rc;
194 }                                                 194 }
195                                                   195 
196 /**                                               196 /**
197  * token_default() - Determine if the given to    197  * token_default() - Determine if the given token is "DEFAULT".
198  * @token: Supplies the token string to be com    198  * @token: Supplies the token string to be compared.
199  *                                                199  *
200  * Return:                                        200  * Return:
201  * * %false     - The token is not "DEFAULT"      201  * * %false     - The token is not "DEFAULT"
202  * * %true      - The token is "DEFAULT"          202  * * %true      - The token is "DEFAULT"
203  */                                               203  */
204 static bool token_default(char *token)            204 static bool token_default(char *token)
205 {                                                 205 {
206         return !strcmp(token, "DEFAULT");         206         return !strcmp(token, "DEFAULT");
207 }                                                 207 }
208                                                   208 
209 /**                                               209 /**
210  * free_rule() - Free the supplied ipe_rule st    210  * free_rule() - Free the supplied ipe_rule struct.
211  * @r: Supplies the ipe_rule struct to be free    211  * @r: Supplies the ipe_rule struct to be freed.
212  *                                                212  *
213  * Free a ipe_rule struct @r. Note @r must be     213  * Free a ipe_rule struct @r. Note @r must be removed from any lists before
214  * calling this function.                         214  * calling this function.
215  */                                               215  */
216 static void free_rule(struct ipe_rule *r)         216 static void free_rule(struct ipe_rule *r)
217 {                                                 217 {
218         struct ipe_prop *p, *t;                   218         struct ipe_prop *p, *t;
219                                                   219 
220         if (IS_ERR_OR_NULL(r))                    220         if (IS_ERR_OR_NULL(r))
221                 return;                           221                 return;
222                                                   222 
223         list_for_each_entry_safe(p, t, &r->pro    223         list_for_each_entry_safe(p, t, &r->props, next) {
224                 list_del(&p->next);               224                 list_del(&p->next);
225                 ipe_digest_free(p->value);        225                 ipe_digest_free(p->value);
226                 kfree(p);                         226                 kfree(p);
227         }                                         227         }
228                                                   228 
229         kfree(r);                                 229         kfree(r);
230 }                                                 230 }
231                                                   231 
232 static const match_table_t operation_tokens =     232 static const match_table_t operation_tokens = {
233         {IPE_OP_EXEC,                   "op=EX    233         {IPE_OP_EXEC,                   "op=EXECUTE"},
234         {IPE_OP_FIRMWARE,               "op=FI    234         {IPE_OP_FIRMWARE,               "op=FIRMWARE"},
235         {IPE_OP_KERNEL_MODULE,          "op=KM    235         {IPE_OP_KERNEL_MODULE,          "op=KMODULE"},
236         {IPE_OP_KEXEC_IMAGE,            "op=KE    236         {IPE_OP_KEXEC_IMAGE,            "op=KEXEC_IMAGE"},
237         {IPE_OP_KEXEC_INITRAMFS,        "op=KE    237         {IPE_OP_KEXEC_INITRAMFS,        "op=KEXEC_INITRAMFS"},
238         {IPE_OP_POLICY,                 "op=PO    238         {IPE_OP_POLICY,                 "op=POLICY"},
239         {IPE_OP_X509,                   "op=X5    239         {IPE_OP_X509,                   "op=X509_CERT"},
240         {IPE_OP_INVALID,                NULL}     240         {IPE_OP_INVALID,                NULL}
241 };                                                241 };
242                                                   242 
243 /**                                               243 /**
244  * parse_operation() - Parse the operation typ    244  * parse_operation() - Parse the operation type given a token string.
245  * @t: Supplies the token string to be parsed.    245  * @t: Supplies the token string to be parsed.
246  *                                                246  *
247  * Return: The parsed operation type.             247  * Return: The parsed operation type.
248  */                                               248  */
249 static enum ipe_op_type parse_operation(char *    249 static enum ipe_op_type parse_operation(char *t)
250 {                                                 250 {
251         substring_t args[MAX_OPT_ARGS];           251         substring_t args[MAX_OPT_ARGS];
252                                                   252 
253         return match_token(t, operation_tokens    253         return match_token(t, operation_tokens, args);
254 }                                                 254 }
255                                                   255 
256 static const match_table_t action_tokens = {      256 static const match_table_t action_tokens = {
257         {IPE_ACTION_ALLOW,      "action=ALLOW"    257         {IPE_ACTION_ALLOW,      "action=ALLOW"},
258         {IPE_ACTION_DENY,       "action=DENY"}    258         {IPE_ACTION_DENY,       "action=DENY"},
259         {IPE_ACTION_INVALID,    NULL}             259         {IPE_ACTION_INVALID,    NULL}
260 };                                                260 };
261                                                   261 
262 /**                                               262 /**
263  * parse_action() - Parse the action type give    263  * parse_action() - Parse the action type given a token string.
264  * @t: Supplies the token string to be parsed.    264  * @t: Supplies the token string to be parsed.
265  *                                                265  *
266  * Return: The parsed action type.                266  * Return: The parsed action type.
267  */                                               267  */
268 static enum ipe_action_type parse_action(char     268 static enum ipe_action_type parse_action(char *t)
269 {                                                 269 {
270         substring_t args[MAX_OPT_ARGS];           270         substring_t args[MAX_OPT_ARGS];
271                                                   271 
272         return match_token(t, action_tokens, a    272         return match_token(t, action_tokens, args);
273 }                                                 273 }
274                                                   274 
275 static const match_table_t property_tokens = {    275 static const match_table_t property_tokens = {
276         {IPE_PROP_BOOT_VERIFIED_FALSE,  "boot_    276         {IPE_PROP_BOOT_VERIFIED_FALSE,  "boot_verified=FALSE"},
277         {IPE_PROP_BOOT_VERIFIED_TRUE,   "boot_    277         {IPE_PROP_BOOT_VERIFIED_TRUE,   "boot_verified=TRUE"},
278         {IPE_PROP_DMV_ROOTHASH,         "dmver    278         {IPE_PROP_DMV_ROOTHASH,         "dmverity_roothash=%s"},
279         {IPE_PROP_DMV_SIG_FALSE,        "dmver    279         {IPE_PROP_DMV_SIG_FALSE,        "dmverity_signature=FALSE"},
280         {IPE_PROP_DMV_SIG_TRUE,         "dmver    280         {IPE_PROP_DMV_SIG_TRUE,         "dmverity_signature=TRUE"},
281         {IPE_PROP_FSV_DIGEST,           "fsver    281         {IPE_PROP_FSV_DIGEST,           "fsverity_digest=%s"},
282         {IPE_PROP_FSV_SIG_FALSE,        "fsver    282         {IPE_PROP_FSV_SIG_FALSE,        "fsverity_signature=FALSE"},
283         {IPE_PROP_FSV_SIG_TRUE,         "fsver    283         {IPE_PROP_FSV_SIG_TRUE,         "fsverity_signature=TRUE"},
284         {IPE_PROP_INVALID,              NULL}     284         {IPE_PROP_INVALID,              NULL}
285 };                                                285 };
286                                                   286 
287 /**                                               287 /**
288  * parse_property() - Parse a rule property gi    288  * parse_property() - Parse a rule property given a token string.
289  * @t: Supplies the token string to be parsed.    289  * @t: Supplies the token string to be parsed.
290  * @r: Supplies the ipe_rule the parsed proper    290  * @r: Supplies the ipe_rule the parsed property will be associated with.
291  *                                                291  *
292  * This function parses and associates a prope    292  * This function parses and associates a property with an IPE rule based
293  * on a token string.                             293  * on a token string.
294  *                                                294  *
295  * Return:                                        295  * Return:
296  * * %0         - Success                         296  * * %0         - Success
297  * * %-ENOMEM   - Out of memory (OOM)             297  * * %-ENOMEM   - Out of memory (OOM)
298  * * %-EBADMSG  - The supplied token cannot be    298  * * %-EBADMSG  - The supplied token cannot be parsed
299  */                                               299  */
300 static int parse_property(char *t, struct ipe_    300 static int parse_property(char *t, struct ipe_rule *r)
301 {                                                 301 {
302         substring_t args[MAX_OPT_ARGS];           302         substring_t args[MAX_OPT_ARGS];
303         struct ipe_prop *p = NULL;                303         struct ipe_prop *p = NULL;
304         int rc = 0;                               304         int rc = 0;
305         int token;                                305         int token;
306         char *dup = NULL;                         306         char *dup = NULL;
307                                                   307 
308         p = kzalloc(sizeof(*p), GFP_KERNEL);      308         p = kzalloc(sizeof(*p), GFP_KERNEL);
309         if (!p)                                   309         if (!p)
310                 return -ENOMEM;                   310                 return -ENOMEM;
311                                                   311 
312         token = match_token(t, property_tokens    312         token = match_token(t, property_tokens, args);
313                                                   313 
314         switch (token) {                          314         switch (token) {
315         case IPE_PROP_DMV_ROOTHASH:               315         case IPE_PROP_DMV_ROOTHASH:
316         case IPE_PROP_FSV_DIGEST:                 316         case IPE_PROP_FSV_DIGEST:
317                 dup = match_strdup(&args[0]);     317                 dup = match_strdup(&args[0]);
318                 if (!dup) {                       318                 if (!dup) {
319                         rc = -ENOMEM;             319                         rc = -ENOMEM;
320                         goto err;                 320                         goto err;
321                 }                                 321                 }
322                 p->value = ipe_digest_parse(du    322                 p->value = ipe_digest_parse(dup);
323                 if (IS_ERR(p->value)) {           323                 if (IS_ERR(p->value)) {
324                         rc = PTR_ERR(p->value)    324                         rc = PTR_ERR(p->value);
325                         goto err;                 325                         goto err;
326                 }                                 326                 }
327                 fallthrough;                      327                 fallthrough;
328         case IPE_PROP_BOOT_VERIFIED_FALSE:        328         case IPE_PROP_BOOT_VERIFIED_FALSE:
329         case IPE_PROP_BOOT_VERIFIED_TRUE:         329         case IPE_PROP_BOOT_VERIFIED_TRUE:
330         case IPE_PROP_DMV_SIG_FALSE:              330         case IPE_PROP_DMV_SIG_FALSE:
331         case IPE_PROP_DMV_SIG_TRUE:               331         case IPE_PROP_DMV_SIG_TRUE:
332         case IPE_PROP_FSV_SIG_FALSE:              332         case IPE_PROP_FSV_SIG_FALSE:
333         case IPE_PROP_FSV_SIG_TRUE:               333         case IPE_PROP_FSV_SIG_TRUE:
334                 p->type = token;                  334                 p->type = token;
335                 break;                            335                 break;
336         default:                                  336         default:
337                 rc = -EBADMSG;                    337                 rc = -EBADMSG;
338                 break;                            338                 break;
339         }                                         339         }
340         if (rc)                                   340         if (rc)
341                 goto err;                         341                 goto err;
342         list_add_tail(&p->next, &r->props);       342         list_add_tail(&p->next, &r->props);
343                                                   343 
344 out:                                              344 out:
345         kfree(dup);                               345         kfree(dup);
346         return rc;                                346         return rc;
347 err:                                              347 err:
348         kfree(p);                                 348         kfree(p);
349         goto out;                                 349         goto out;
350 }                                                 350 }
351                                                   351 
352 /**                                               352 /**
353  * parse_rule() - parse a policy rule line.       353  * parse_rule() - parse a policy rule line.
354  * @line: Supplies rule line to be parsed.        354  * @line: Supplies rule line to be parsed.
355  * @p: Supplies the partial parsed policy.        355  * @p: Supplies the partial parsed policy.
356  *                                                356  *
357  * Return:                                        357  * Return:
358  * * 0          - Success                         358  * * 0          - Success
359  * * %-ENOMEM   - Out of memory (OOM)             359  * * %-ENOMEM   - Out of memory (OOM)
360  * * %-EBADMSG  - Policy syntax error             360  * * %-EBADMSG  - Policy syntax error
361  */                                               361  */
362 static int parse_rule(char *line, struct ipe_p    362 static int parse_rule(char *line, struct ipe_parsed_policy *p)
363 {                                                 363 {
364         enum ipe_action_type action = IPE_ACTI    364         enum ipe_action_type action = IPE_ACTION_INVALID;
365         enum ipe_op_type op = IPE_OP_INVALID;     365         enum ipe_op_type op = IPE_OP_INVALID;
366         bool is_default_rule = false;             366         bool is_default_rule = false;
367         struct ipe_rule *r = NULL;                367         struct ipe_rule *r = NULL;
368         bool first_token = true;                  368         bool first_token = true;
369         bool op_parsed = false;                   369         bool op_parsed = false;
370         int rc = 0;                               370         int rc = 0;
371         char *t;                                  371         char *t;
372                                                   372 
373         if (IS_ERR_OR_NULL(line))                 373         if (IS_ERR_OR_NULL(line))
374                 return -EBADMSG;                  374                 return -EBADMSG;
375                                                   375 
376         r = kzalloc(sizeof(*r), GFP_KERNEL);      376         r = kzalloc(sizeof(*r), GFP_KERNEL);
377         if (!r)                                   377         if (!r)
378                 return -ENOMEM;                   378                 return -ENOMEM;
379                                                   379 
380         INIT_LIST_HEAD(&r->next);                 380         INIT_LIST_HEAD(&r->next);
381         INIT_LIST_HEAD(&r->props);                381         INIT_LIST_HEAD(&r->props);
382                                                   382 
383         while (t = strsep(&line, IPE_POLICY_DE    383         while (t = strsep(&line, IPE_POLICY_DELIM), line) {
384                 if (*t == '\0')                   384                 if (*t == '\0')
385                         continue;                 385                         continue;
386                 if (first_token && token_defau    386                 if (first_token && token_default(t)) {
387                         is_default_rule = true    387                         is_default_rule = true;
388                 } else {                          388                 } else {
389                         if (!op_parsed) {         389                         if (!op_parsed) {
390                                 op = parse_ope    390                                 op = parse_operation(t);
391                                 if (op == IPE_    391                                 if (op == IPE_OP_INVALID)
392                                         rc = -    392                                         rc = -EBADMSG;
393                                 else              393                                 else
394                                         op_par    394                                         op_parsed = true;
395                         } else {                  395                         } else {
396                                 rc = parse_pro    396                                 rc = parse_property(t, r);
397                         }                         397                         }
398                 }                                 398                 }
399                                                   399 
400                 if (rc)                           400                 if (rc)
401                         goto err;                 401                         goto err;
402                 first_token = false;              402                 first_token = false;
403         }                                         403         }
404                                                   404 
405         action = parse_action(t);                 405         action = parse_action(t);
406         if (action == IPE_ACTION_INVALID) {       406         if (action == IPE_ACTION_INVALID) {
407                 rc = -EBADMSG;                    407                 rc = -EBADMSG;
408                 goto err;                         408                 goto err;
409         }                                         409         }
410                                                   410 
411         if (is_default_rule) {                    411         if (is_default_rule) {
412                 if (!list_empty(&r->props)) {     412                 if (!list_empty(&r->props)) {
413                         rc = -EBADMSG;            413                         rc = -EBADMSG;
414                 } else if (op == IPE_OP_INVALI    414                 } else if (op == IPE_OP_INVALID) {
415                         if (p->global_default_    415                         if (p->global_default_action != IPE_ACTION_INVALID)
416                                 rc = -EBADMSG;    416                                 rc = -EBADMSG;
417                         else                      417                         else
418                                 p->global_defa    418                                 p->global_default_action = action;
419                 } else {                          419                 } else {
420                         if (p->rules[op].defau    420                         if (p->rules[op].default_action != IPE_ACTION_INVALID)
421                                 rc = -EBADMSG;    421                                 rc = -EBADMSG;
422                         else                      422                         else
423                                 p->rules[op].d    423                                 p->rules[op].default_action = action;
424                 }                                 424                 }
425         } else if (op != IPE_OP_INVALID && act    425         } else if (op != IPE_OP_INVALID && action != IPE_ACTION_INVALID) {
426                 r->op = op;                       426                 r->op = op;
427                 r->action = action;               427                 r->action = action;
428         } else {                                  428         } else {
429                 rc = -EBADMSG;                    429                 rc = -EBADMSG;
430         }                                         430         }
431                                                   431 
432         if (rc)                                   432         if (rc)
433                 goto err;                         433                 goto err;
434         if (!is_default_rule)                     434         if (!is_default_rule)
435                 list_add_tail(&r->next, &p->ru    435                 list_add_tail(&r->next, &p->rules[op].rules);
436         else                                      436         else
437                 free_rule(r);                     437                 free_rule(r);
438                                                   438 
439         return rc;                                439         return rc;
440 err:                                              440 err:
441         free_rule(r);                             441         free_rule(r);
442         return rc;                                442         return rc;
443 }                                                 443 }
444                                                   444 
445 /**                                               445 /**
446  * ipe_free_parsed_policy() - free a parsed po    446  * ipe_free_parsed_policy() - free a parsed policy structure.
447  * @p: Supplies the parsed policy.                447  * @p: Supplies the parsed policy.
448  */                                               448  */
449 void ipe_free_parsed_policy(struct ipe_parsed_    449 void ipe_free_parsed_policy(struct ipe_parsed_policy *p)
450 {                                                 450 {
451         struct ipe_rule *pp, *t;                  451         struct ipe_rule *pp, *t;
452         size_t i = 0;                             452         size_t i = 0;
453                                                   453 
454         if (IS_ERR_OR_NULL(p))                    454         if (IS_ERR_OR_NULL(p))
455                 return;                           455                 return;
456                                                   456 
457         for (i = 0; i < ARRAY_SIZE(p->rules);     457         for (i = 0; i < ARRAY_SIZE(p->rules); ++i)
458                 list_for_each_entry_safe(pp, t    458                 list_for_each_entry_safe(pp, t, &p->rules[i].rules, next) {
459                         list_del(&pp->next);      459                         list_del(&pp->next);
460                         free_rule(pp);            460                         free_rule(pp);
461                 }                                 461                 }
462                                                   462 
463         kfree(p->name);                           463         kfree(p->name);
464         kfree(p);                                 464         kfree(p);
465 }                                                 465 }
466                                                   466 
467 /**                                               467 /**
468  * validate_policy() - validate a parsed polic    468  * validate_policy() - validate a parsed policy.
469  * @p: Supplies the fully parsed policy.          469  * @p: Supplies the fully parsed policy.
470  *                                                470  *
471  * Given a policy structure that was just pars    471  * Given a policy structure that was just parsed, validate that all
472  * operations have their default rules or a gl    472  * operations have their default rules or a global default rule is set.
473  *                                                473  *
474  * Return:                                        474  * Return:
475  * * %0         - Success                         475  * * %0         - Success
476  * * %-EBADMSG  - Policy is invalid               476  * * %-EBADMSG  - Policy is invalid
477  */                                               477  */
478 static int validate_policy(const struct ipe_pa    478 static int validate_policy(const struct ipe_parsed_policy *p)
479 {                                                 479 {
480         size_t i = 0;                             480         size_t i = 0;
481                                                   481 
482         if (p->global_default_action != IPE_AC    482         if (p->global_default_action != IPE_ACTION_INVALID)
483                 return 0;                         483                 return 0;
484                                                   484 
485         for (i = 0; i < ARRAY_SIZE(p->rules);     485         for (i = 0; i < ARRAY_SIZE(p->rules); ++i) {
486                 if (p->rules[i].default_action    486                 if (p->rules[i].default_action == IPE_ACTION_INVALID)
487                         return -EBADMSG;          487                         return -EBADMSG;
488         }                                         488         }
489                                                   489 
490         return 0;                                 490         return 0;
491 }                                                 491 }
492                                                   492 
493 /**                                               493 /**
494  * ipe_parse_policy() - Given a string, parse     494  * ipe_parse_policy() - Given a string, parse the string into an IPE policy.
495  * @p: partially filled ipe_policy structure t    495  * @p: partially filled ipe_policy structure to populate with the result.
496  *     it must have text and textlen set.         496  *     it must have text and textlen set.
497  *                                                497  *
498  * Return:                                        498  * Return:
499  * * %0         - Success                         499  * * %0         - Success
500  * * %-EBADMSG  - Policy is invalid               500  * * %-EBADMSG  - Policy is invalid
501  * * %-ENOMEM   - Out of Memory                   501  * * %-ENOMEM   - Out of Memory
502  * * %-ERANGE   - Policy version number overfl    502  * * %-ERANGE   - Policy version number overflow
503  * * %-EINVAL   - Policy version parsing error    503  * * %-EINVAL   - Policy version parsing error
504  */                                               504  */
505 int ipe_parse_policy(struct ipe_policy *p)        505 int ipe_parse_policy(struct ipe_policy *p)
506 {                                                 506 {
507         struct ipe_parsed_policy *pp = NULL;      507         struct ipe_parsed_policy *pp = NULL;
508         char *policy = NULL, *dup = NULL;         508         char *policy = NULL, *dup = NULL;
509         bool header_parsed = false;               509         bool header_parsed = false;
510         char *line = NULL;                        510         char *line = NULL;
511         size_t len;                               511         size_t len;
512         int rc = 0;                               512         int rc = 0;
513                                                   513 
514         if (!p->textlen)                          514         if (!p->textlen)
515                 return -EBADMSG;                  515                 return -EBADMSG;
516                                                   516 
517         policy = kmemdup_nul(p->text, p->textl    517         policy = kmemdup_nul(p->text, p->textlen, GFP_KERNEL);
518         if (!policy)                              518         if (!policy)
519                 return -ENOMEM;                   519                 return -ENOMEM;
520         dup = policy;                             520         dup = policy;
521                                                   521 
522         pp = new_parsed_policy();                 522         pp = new_parsed_policy();
523         if (IS_ERR(pp)) {                         523         if (IS_ERR(pp)) {
524                 rc = PTR_ERR(pp);                 524                 rc = PTR_ERR(pp);
525                 goto out;                         525                 goto out;
526         }                                         526         }
527                                                   527 
528         while ((line = strsep(&policy, IPE_LIN    528         while ((line = strsep(&policy, IPE_LINE_DELIM)) != NULL) {
529                 remove_comment(line);             529                 remove_comment(line);
530                 len = remove_trailing_spaces(l    530                 len = remove_trailing_spaces(line);
531                 if (!len)                         531                 if (!len)
532                         continue;                 532                         continue;
533                                                   533 
534                 if (!header_parsed) {             534                 if (!header_parsed) {
535                         rc = parse_header(line    535                         rc = parse_header(line, pp);
536                         if (rc)                   536                         if (rc)
537                                 goto err;         537                                 goto err;
538                         header_parsed = true;     538                         header_parsed = true;
539                 } else {                          539                 } else {
540                         rc = parse_rule(line,     540                         rc = parse_rule(line, pp);
541                         if (rc)                   541                         if (rc)
542                                 goto err;         542                                 goto err;
543                 }                                 543                 }
544         }                                         544         }
545                                                   545 
546         if (!header_parsed || validate_policy(    546         if (!header_parsed || validate_policy(pp)) {
547                 rc = -EBADMSG;                    547                 rc = -EBADMSG;
548                 goto err;                         548                 goto err;
549         }                                         549         }
550                                                   550 
551         p->parsed = pp;                           551         p->parsed = pp;
552                                                   552 
553 out:                                              553 out:
554         kfree(dup);                               554         kfree(dup);
555         return rc;                                555         return rc;
556 err:                                              556 err:
557         ipe_free_parsed_policy(pp);               557         ipe_free_parsed_policy(pp);
558         goto out;                                 558         goto out;
559 }                                                 559 }
560                                                   560 

~ [ 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