1 /*
2 * This work is based on the LSM implementation in Linux 2.6.13.4.
3 *
4 * Author: George Coker, <gscoker@alpha.ncsc.mil>
5 *
6 * Contributors: Michael LeMay, <mdlemay@epoch.ncsc.mil>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2,
10 * as published by the Free Software Foundation.
11 */
12
13 #include <xen/init.h>
14 #include <xen/errno.h>
15 #include <xen/lib.h>
16 #include <xen/param.h>
17
18 #include <xen/hypercall.h>
19 #include <xsm/xsm.h>
20
21 #ifdef CONFIG_XSM
22
23 #ifdef CONFIG_MULTIBOOT
24 #include <asm/setup.h>
25 #endif
26
27 #ifdef CONFIG_HAS_DEVICE_TREE
28 #include <asm/setup.h>
29 #endif
30
31 #define XSM_FRAMEWORK_VERSION "1.0.0"
32
33 struct xsm_operations *xsm_ops;
34
35 enum xsm_bootparam {
36 XSM_BOOTPARAM_DUMMY,
37 XSM_BOOTPARAM_FLASK,
38 XSM_BOOTPARAM_SILO,
39 };
40
41 static enum xsm_bootparam __initdata xsm_bootparam =
42 #ifdef CONFIG_XSM_FLASK_DEFAULT
43 XSM_BOOTPARAM_FLASK;
44 #elif CONFIG_XSM_SILO_DEFAULT
45 XSM_BOOTPARAM_SILO;
46 #else
47 XSM_BOOTPARAM_DUMMY;
48 #endif
49
parse_xsm_param(const char * s)50 static int __init parse_xsm_param(const char *s)
51 {
52 int rc = 0;
53
54 if ( !strcmp(s, "dummy") )
55 xsm_bootparam = XSM_BOOTPARAM_DUMMY;
56 #ifdef CONFIG_XSM_FLASK
57 else if ( !strcmp(s, "flask") )
58 xsm_bootparam = XSM_BOOTPARAM_FLASK;
59 #endif
60 #ifdef CONFIG_XSM_SILO
61 else if ( !strcmp(s, "silo") )
62 xsm_bootparam = XSM_BOOTPARAM_SILO;
63 #endif
64 else
65 rc = -EINVAL;
66
67 return rc;
68 }
69 custom_param("xsm", parse_xsm_param);
70
verify(struct xsm_operations * ops)71 static inline int verify(struct xsm_operations *ops)
72 {
73 /* verify the security_operations structure exists */
74 if ( !ops )
75 return -EINVAL;
76 xsm_fixup_ops(ops);
77 return 0;
78 }
79
xsm_core_init(const void * policy_buffer,size_t policy_size)80 static int __init xsm_core_init(const void *policy_buffer, size_t policy_size)
81 {
82 #ifdef CONFIG_XSM_FLASK_POLICY
83 if ( policy_size == 0 )
84 {
85 policy_buffer = xsm_flask_init_policy;
86 policy_size = xsm_flask_init_policy_size;
87 }
88 #endif
89
90 if ( verify(&dummy_xsm_ops) )
91 {
92 printk(XENLOG_ERR "Could not verify dummy_xsm_ops structure\n");
93 return -EIO;
94 }
95
96 xsm_ops = &dummy_xsm_ops;
97
98 switch ( xsm_bootparam )
99 {
100 case XSM_BOOTPARAM_DUMMY:
101 break;
102
103 case XSM_BOOTPARAM_FLASK:
104 flask_init(policy_buffer, policy_size);
105 break;
106
107 case XSM_BOOTPARAM_SILO:
108 silo_init();
109 break;
110
111 default:
112 ASSERT_UNREACHABLE();
113 break;
114 }
115
116 return 0;
117 }
118
119 #ifdef CONFIG_MULTIBOOT
xsm_multiboot_init(unsigned long * module_map,const multiboot_info_t * mbi)120 int __init xsm_multiboot_init(unsigned long *module_map,
121 const multiboot_info_t *mbi)
122 {
123 int ret = 0;
124 void *policy_buffer = NULL;
125 size_t policy_size = 0;
126
127 printk("XSM Framework v" XSM_FRAMEWORK_VERSION " initialized\n");
128
129 if ( XSM_MAGIC )
130 {
131 ret = xsm_multiboot_policy_init(module_map, mbi,
132 &policy_buffer, &policy_size);
133 if ( ret )
134 {
135 bootstrap_map(NULL);
136 printk(XENLOG_ERR "Error %d initializing XSM policy\n", ret);
137 return -EINVAL;
138 }
139 }
140
141 ret = xsm_core_init(policy_buffer, policy_size);
142 bootstrap_map(NULL);
143
144 return 0;
145 }
146 #endif
147
148 #ifdef CONFIG_HAS_DEVICE_TREE
xsm_dt_init(void)149 int __init xsm_dt_init(void)
150 {
151 int ret = 0;
152 void *policy_buffer = NULL;
153 size_t policy_size = 0;
154
155 printk("XSM Framework v" XSM_FRAMEWORK_VERSION " initialized\n");
156
157 if ( XSM_MAGIC )
158 {
159 ret = xsm_dt_policy_init(&policy_buffer, &policy_size);
160 if ( ret )
161 {
162 printk(XENLOG_ERR "Error %d initializing XSM policy\n", ret);
163 return -EINVAL;
164 }
165 }
166
167 ret = xsm_core_init(policy_buffer, policy_size);
168
169 xfree(policy_buffer);
170
171 return ret ?: (xsm_bootparam == XSM_BOOTPARAM_SILO);
172 }
173
174 /**
175 * has_xsm_magic - Check XSM Magic of the module header by phy address
176 * A XSM module has a special header
177 * ------------------------------------------------
178 * uint magic | uint target_len | uchar target[8] |
179 * 0xf97cff8c | 8 | "XenFlask" |
180 * ------------------------------------------------
181 * 0xf97cff8c is policy magic number (XSM_MAGIC).
182 * Here we only check the "magic" of the module.
183 */
has_xsm_magic(paddr_t start)184 bool __init has_xsm_magic(paddr_t start)
185 {
186 xsm_magic_t magic;
187
188 if ( XSM_MAGIC )
189 {
190 copy_from_paddr(&magic, start, sizeof(magic) );
191 return ( magic == XSM_MAGIC );
192 }
193
194 return false;
195 }
196 #endif
197
register_xsm(struct xsm_operations * ops)198 int __init register_xsm(struct xsm_operations *ops)
199 {
200 if ( verify(ops) )
201 {
202 printk(XENLOG_ERR "Could not verify xsm_operations structure\n");
203 return -EINVAL;
204 }
205
206 if ( xsm_ops != &dummy_xsm_ops )
207 return -EAGAIN;
208
209 xsm_ops = ops;
210
211 return 0;
212 }
213
214 #endif
215
do_xsm_op(XEN_GUEST_HANDLE_PARAM (xsm_op_t)op)216 long do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op)
217 {
218 return xsm_do_xsm_op(op);
219 }
220
221 #ifdef CONFIG_COMPAT
compat_xsm_op(XEN_GUEST_HANDLE_PARAM (xsm_op_t)op)222 int compat_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op)
223 {
224 return xsm_do_compat_op(op);
225 }
226 #endif
227