xref: /third_party/selinux/libsepol/cil/src/cil_fqn.c (revision 6cd6a6ac)
1/*
2 * Copyright 2011 Tresys Technology, LLC. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 *    1. Redistributions of source code must retain the above copyright notice,
8 *       this list of conditions and the following disclaimer.
9 *
10 *    2. Redistributions in binary form must reproduce the above copyright notice,
11 *       this list of conditions and the following disclaimer in the documentation
12 *       and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * The views and conclusions contained in the software and documentation are those
26 * of the authors and should not be interpreted as representing official policies,
27 * either expressed or implied, of Tresys Technology, LLC.
28 */
29
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33
34#include "cil_fqn.h"
35#include "cil_internal.h"
36#include "cil_log.h"
37#include "cil_strpool.h"
38#include "cil_symtab.h"
39
40struct cil_fqn_args {
41	char prefix[CIL_MAX_NAME_LENGTH];
42	int len;
43	struct cil_tree_node *node;
44};
45
46static int __cil_fqn_qualify_decls(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
47{
48	struct cil_fqn_args *fqn_args = args;
49	struct cil_symtab_datum *datum = (struct cil_symtab_datum *)d;
50	int newlen;
51	char prefix[CIL_MAX_NAME_LENGTH];
52	int rc = SEPOL_OK;
53
54	if (fqn_args->len == 0) {
55		goto exit;
56	}
57
58	newlen = fqn_args->len + strlen(datum->name);
59	if (newlen >= CIL_MAX_NAME_LENGTH) {
60		cil_log(CIL_INFO, "Fully qualified name for %s is too long\n", datum->name);
61		rc = SEPOL_ERR;
62		goto exit;
63	}
64	strcpy(prefix, fqn_args->prefix);
65	strcat(prefix, datum->name);
66	datum->fqn = cil_strpool_add(prefix);
67
68exit:
69	return rc;
70}
71
72static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
73{
74	struct cil_fqn_args *fqn_args = args;
75	struct cil_fqn_args child_args;
76	struct cil_block *block = (struct cil_block *)d;
77	struct cil_symtab_datum *datum = (struct cil_symtab_datum *)block;
78	struct cil_tree_node *node = NODE(datum);
79	int i;
80	int rc = SEPOL_OK;
81	int newlen;
82
83	if (node->flavor != CIL_BLOCK) {
84		goto exit;
85	}
86
87	newlen = fqn_args->len + strlen(datum->name) + 1;
88	if (newlen >= CIL_MAX_NAME_LENGTH) {
89		cil_log(CIL_INFO, "Fully qualified name for block %s is too long\n", datum->name);
90		rc = SEPOL_ERR;
91		goto exit;
92	}
93
94	child_args.node = node;
95	child_args.len = newlen;
96	strcpy(child_args.prefix, fqn_args->prefix);
97	strcat(child_args.prefix, datum->name);
98	strcat(child_args.prefix, ".");
99
100	for (i=1; i<CIL_SYM_NUM; i++) {
101		switch (i) {
102		case CIL_SYM_CLASSPERMSETS:
103		case CIL_SYM_CONTEXTS:
104		case CIL_SYM_LEVELRANGES:
105		case CIL_SYM_IPADDRS:
106		case CIL_SYM_NAMES:
107		case CIL_SYM_PERMX:
108			/* These do not show up in the kernel policy */
109			break;
110		case CIL_SYM_POLICYCAPS:
111			/* Valid policy capability names are defined in libsepol */
112			break;
113		default:
114			rc = cil_symtab_map(&(block->symtab[i]), __cil_fqn_qualify_decls, &child_args);
115			if (rc != SEPOL_OK) {
116				goto exit;
117			}
118			break;
119		}
120	}
121
122	rc = cil_symtab_map(&(block->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &child_args);
123
124exit:
125	if (rc != SEPOL_OK) {
126		cil_tree_log(node, CIL_ERR,"Problem qualifying names in block");
127	}
128
129	return rc;
130}
131
132int cil_fqn_qualify(struct cil_tree_node *root_node)
133{
134	struct cil_root *root = root_node->data;
135	struct cil_fqn_args fqn_args;
136
137	fqn_args.prefix[0] = '\0';
138	fqn_args.len = 0;
139	fqn_args.node = root_node;
140
141	return cil_symtab_map(&(root->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &fqn_args);
142}
143
144