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