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
17 #include <xen/hypercall.h>
18 #include <xsm/xsm.h>
19
20 #ifdef CONFIG_XSM
21
22 #ifdef CONFIG_HAS_DEVICE_TREE
23 #include <asm/setup.h>
24 #endif
25
26 #define XSM_FRAMEWORK_VERSION "1.0.0"
27
28 struct xsm_operations *xsm_ops;
29
verify(struct xsm_operations * ops)30 static inline int verify(struct xsm_operations *ops)
31 {
32 /* verify the security_operations structure exists */
33 if ( !ops )
34 return -EINVAL;
35 xsm_fixup_ops(ops);
36 return 0;
37 }
38
xsm_core_init(const void * policy_buffer,size_t policy_size)39 static int __init xsm_core_init(const void *policy_buffer, size_t policy_size)
40 {
41 #ifdef CONFIG_XSM_POLICY
42 if ( policy_size == 0 )
43 {
44 policy_buffer = xsm_init_policy;
45 policy_size = xsm_init_policy_size;
46 }
47 #endif
48
49 if ( verify(&dummy_xsm_ops) )
50 {
51 printk(XENLOG_ERR "Could not verify dummy_xsm_ops structure\n");
52 return -EIO;
53 }
54
55 xsm_ops = &dummy_xsm_ops;
56 flask_init(policy_buffer, policy_size);
57
58 return 0;
59 }
60
61 #ifdef CONFIG_MULTIBOOT
xsm_multiboot_init(unsigned long * module_map,const multiboot_info_t * mbi,void * (* bootstrap_map)(const module_t *))62 int __init xsm_multiboot_init(unsigned long *module_map,
63 const multiboot_info_t *mbi,
64 void *(*bootstrap_map)(const module_t *))
65 {
66 int ret = 0;
67 void *policy_buffer = NULL;
68 size_t policy_size = 0;
69
70 printk("XSM Framework v" XSM_FRAMEWORK_VERSION " initialized\n");
71
72 if ( XSM_MAGIC )
73 {
74 ret = xsm_multiboot_policy_init(module_map, mbi, bootstrap_map,
75 &policy_buffer, &policy_size);
76 if ( ret )
77 {
78 bootstrap_map(NULL);
79 printk(XENLOG_ERR "Error %d initializing XSM policy\n", ret);
80 return -EINVAL;
81 }
82 }
83
84 ret = xsm_core_init(policy_buffer, policy_size);
85 bootstrap_map(NULL);
86
87 return 0;
88 }
89 #endif
90
91 #ifdef CONFIG_HAS_DEVICE_TREE
xsm_dt_init(void)92 int __init xsm_dt_init(void)
93 {
94 int ret = 0;
95 void *policy_buffer = NULL;
96 size_t policy_size = 0;
97
98 printk("XSM Framework v" XSM_FRAMEWORK_VERSION " initialized\n");
99
100 if ( XSM_MAGIC )
101 {
102 ret = xsm_dt_policy_init(&policy_buffer, &policy_size);
103 if ( ret )
104 {
105 printk(XENLOG_ERR "Error %d initializing XSM policy\n", ret);
106 return -EINVAL;
107 }
108 }
109
110 ret = xsm_core_init(policy_buffer, policy_size);
111
112 xfree(policy_buffer);
113
114 return ret;
115 }
116
117 /**
118 * has_xsm_magic - Check XSM Magic of the module header by phy address
119 * A XSM module has a special header
120 * ------------------------------------------------
121 * uint magic | uint target_len | uchar target[8] |
122 * 0xf97cff8c | 8 | "XenFlask" |
123 * ------------------------------------------------
124 * 0xf97cff8c is policy magic number (XSM_MAGIC).
125 * Here we only check the "magic" of the module.
126 */
has_xsm_magic(paddr_t start)127 bool __init has_xsm_magic(paddr_t start)
128 {
129 xsm_magic_t magic;
130
131 if ( XSM_MAGIC )
132 {
133 copy_from_paddr(&magic, start, sizeof(magic) );
134 return ( magic == XSM_MAGIC );
135 }
136
137 return false;
138 }
139 #endif
140
register_xsm(struct xsm_operations * ops)141 int __init register_xsm(struct xsm_operations *ops)
142 {
143 if ( verify(ops) )
144 {
145 printk(XENLOG_ERR "Could not verify xsm_operations structure\n");
146 return -EINVAL;
147 }
148
149 if ( xsm_ops != &dummy_xsm_ops )
150 return -EAGAIN;
151
152 xsm_ops = ops;
153
154 return 0;
155 }
156
157 #endif
158
do_xsm_op(XEN_GUEST_HANDLE_PARAM (xsm_op_t)op)159 long do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op)
160 {
161 return xsm_do_xsm_op(op);
162 }
163
164 #ifdef CONFIG_COMPAT
compat_xsm_op(XEN_GUEST_HANDLE_PARAM (xsm_op_t)op)165 int compat_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op)
166 {
167 return xsm_do_compat_op(op);
168 }
169 #endif
170