/root/src/xen/xen/xsm/xsm_core.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
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 | | |
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 |
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 |
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 | | */ |
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 | | |
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 | | |
159 | | long do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) |
160 | 3 | { |
161 | 3 | return xsm_do_xsm_op(op); |
162 | 3 | } |
163 | | |
164 | | #ifdef CONFIG_COMPAT |
165 | | int compat_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) |
166 | 0 | { |
167 | 0 | return xsm_do_compat_op(op); |
168 | 0 | } |
169 | | #endif |