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.


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