Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Cleanup of linkage issues for non-Linux hosts
[palacios.git] / linux_module / iface-guard-mods.c
1 /* 
2  * Linux interface for guarded module registration
3  *
4  * (c) Kyle C. Hale 2012
5  *
6  */
7
8 #include <linux/uaccess.h>
9 #include <linux/module.h>
10 #include <linux/types.h>
11 #include <linux/list.h>
12 #include <gears/guard_mods.h>
13 #include "palacios.h"
14 #include "vm.h"
15 #include "linux-exts.h"
16 #include "iface-guard-mods.h"
17
18
19 static int
20 vm_register_mod (struct v3_guest * guest, 
21                  unsigned int cmd,
22                  unsigned long arg,
23                  void * priv_data) 
24 {
25     uint64_t ret;
26     struct v3_guard_mod arg_mod;
27     struct v3_guard_mod * gm;
28     int i;
29
30     gm = palacios_alloc(sizeof(struct v3_guard_mod));
31     if (!gm) {
32         ERROR("palacios: error allocating guarded module\n");
33         return -EFAULT;
34     }
35
36     if (copy_from_user(&arg_mod, (void __user *)arg, sizeof(struct v3_guard_mod))) {
37         ERROR("palacios: error copying guarded module data from userspace\n");
38         return -EFAULT;
39     }
40
41     memcpy(gm, &arg_mod, sizeof(struct v3_guard_mod));
42
43     /* get module name */
44     gm->name = palacios_alloc(strnlen_user((char __user *)arg_mod.name, MAX_MOD_NAME_LEN)+1);
45     if (!gm->name) {
46         ERROR("Problem allocating space for mod name\n");
47         return -1;
48     }
49
50     if (strncpy_from_user(gm->name, (char __user *)arg_mod.name, MAX_MOD_NAME_LEN) == -EFAULT) {
51         ERROR("problem copying from userspace\n");
52         return -1;
53     }
54
55     /* get module content hash */
56     gm->content_hash = palacios_alloc(strnlen_user((char __user *)arg_mod.content_hash, MAX_HASH_LEN)+1);
57     if (!gm->content_hash) {
58         ERROR("Problem allocating space for content hash\n");
59         return -1;
60     }
61
62     if (strncpy_from_user(gm->content_hash, (char __user *)arg_mod.content_hash, MAX_HASH_LEN) == -EFAULT) {
63         ERROR("problem copying from userspace\n");
64         return -1;
65     }
66
67     /* get valid entry points */
68     gm->entry_points = palacios_alloc(sizeof(struct v3_guard_mod)*arg_mod.num_entries);
69     if (!gm->entry_points) {
70         ERROR("Problem allocating space for entry point array\n");
71         return -1;
72     }
73
74     if (copy_from_user(gm->entry_points, (void __user *)arg_mod.entry_points, sizeof(struct v3_guard_mod)*arg_mod.num_entries)
75         == -EFAULT) {
76         ERROR("problem copying from userspace\n");
77         return -1;
78     }
79
80     for (i = 0; i < gm->num_entries; i++) {
81         int len;
82         char * tmp;   
83
84         if ((len = strnlen_user((char __user *)gm->entry_points[i].name, MAX_MOD_NAME_LEN)+1) == -EFAULT) {
85             ERROR("problem getting strlen from userspace\n");
86             return -1;
87         }
88
89         tmp = palacios_alloc(len);
90         if (!tmp) {
91             ERROR("Problem allocating space for string\n");
92             return -1;
93         }
94
95         if (strncpy_from_user(tmp, (char __user *)gm->entry_points[i].name, MAX_MOD_NAME_LEN) == -EFAULT) {
96                 ERROR("problem copying from userspace\n");
97                 return -1;
98         }
99
100         gm->entry_points[i].name = tmp;
101     }
102
103     /* get list of privileges */
104     gm->priv_array = palacios_alloc(sizeof(char*)*arg_mod.num_privs);
105     if (!gm->priv_array) {
106         ERROR("Problem allocating space for privilege array\n");
107         return -1;
108     }
109
110     if (copy_from_user(gm->priv_array, (void __user *)arg_mod.priv_array, sizeof(char*)*arg_mod.num_privs)
111         == -EFAULT) {
112         ERROR("problem copying privilege array from userspace\n");
113         return -1;
114     }
115
116     for (i = 0; i < gm->num_privs; i++) {
117         int len;
118         char * tmp;
119         if ((len = strlen_user((char __user*)gm->priv_array[i]) + 1) == -EFAULT) {
120             ERROR("problem getting strlen from userspace\n");
121             return -1;
122         }
123
124         tmp = palacios_alloc(len);
125         if (!tmp) {
126             ERROR("Problem allocating space for privilege name\n");
127             return -1;
128         }
129
130         if (strncpy_from_user(tmp, (char __user *)gm->priv_array[i], MAX_MOD_NAME_LEN) == -EFAULT) {
131             ERROR("problem copying privilege from userspace\n");
132             return -1;
133         }
134
135         gm->priv_array[i] = tmp;
136     }
137     
138     INFO("Registering Guarded Module with Palacios\n");
139     ret = v3_register_gm(guest->v3_ctx,
140                           gm->name,
141                           gm->content_hash,
142                           gm->hcall_offset,
143                           gm->text_size,
144                           gm->num_entries,
145                           gm->num_privs,
146                           gm->priv_array,
147                           NULL,
148                           (void*)gm->entry_points);
149
150     if (!ret) {
151         ERROR("palacios: could not register guarded module: %s\n", arg_mod.name);
152         return -1;
153     }
154
155     arg_mod.id = ret;
156
157     if (copy_to_user((void __user *)arg, &arg_mod, sizeof(struct v3_guard_mod))) {
158         ERROR("palacios: error copying guarded module back to userspace\n");
159         return -1;
160     }
161
162     palacios_free(gm->name);
163     palacios_free(gm->content_hash);
164     for (i = 0; i < gm->num_entries; i++) {
165         palacios_free(gm->entry_points[i].name);
166     }
167     palacios_free(gm->entry_points);
168     palacios_free(gm);
169     return 0;
170 }
171
172
173 static int 
174 init_guard_mods (void) 
175 {
176     return 0;
177 }
178
179
180 static int 
181 deinit_guard_mods (void) 
182 {
183     return 0;
184 }
185
186
187 static int 
188 guest_init_guard_mods (struct v3_guest * guest, void ** vm_data) 
189 {
190     add_guest_ctrl(guest, V3_VM_REGISTER_MOD, vm_register_mod, NULL);
191     return 0;
192 }
193
194
195 static int 
196 guest_deinit_guard_mods (struct v3_guest * guest, void * vm_data) 
197 {
198     remove_guest_ctrl(guest, V3_VM_REGISTER_MOD);
199     return 0;
200 }
201
202
203 static struct linux_ext guard_mods_ext = {
204     .name = "GUARDED_MODULES",
205     .init = init_guard_mods,
206     .deinit = deinit_guard_mods,
207     .guest_init = guest_init_guard_mods,
208     .guest_deinit = guest_deinit_guard_mods
209 };
210
211 register_extension(&guard_mods_ext);