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.


Add guarded module infrastructure
[palacios.git] / palacios / src / gears / ext_priv.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2012, Kyle C. Hale <kh@u.norhtwestern.edu>
11  * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Kyle C. Hale <kh@u.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_string.h>
22 #include <palacios/vmm_hashtable.h>
23 #include <palacios/vmm_extensions.h>
24 #include <palacios/vmm_decoder.h>
25 #include <palacios/vm_guest.h>
26 #include <palacios/vm_guest_mem.h>
27
28 #include <gears/privilege.h>
29
30 #ifndef V3_CONFIG_DEBUG_EXT_PRIV
31 #undef PrintDebug
32 #define PrintDebug(fmt, args...)
33 #endif
34
35 static struct v3_privileges * global_privs;
36
37 static uint_t 
38 priv_hash_fn (addr_t key) 
39 {
40     return v3_hash_buffer((uint8_t*)key, strlen((char*)key));
41 }
42
43
44 static int 
45 priv_eq_fn (addr_t key1, addr_t key2) 
46 {
47     return (strcmp((char*)key1, (char*)key2) == 0);
48 }
49
50
51 static int 
52 init_priv (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) 
53 {
54     struct v3_privileges * p = V3_Malloc(sizeof(struct v3_privileges));
55
56     global_privs = p;
57
58     if (!p) {
59         PrintError(VM_NONE, VCORE_NONE,"Priv: Problem allocating privileges\n");
60         return -1;
61     }
62
63     INIT_LIST_HEAD(&(p->priv_list));
64
65     *priv_data = p;
66
67     if (!(p->priv_table = v3_create_htable(0, priv_hash_fn, priv_eq_fn))) {
68         PrintError(VM_NONE, VCORE_NONE,"Priv: Problem creating privilege hash table\n");
69         return -1;
70     }
71
72     return 0;
73 }
74
75
76 static int 
77 deinit_priv (struct v3_vm_info * vm, void * priv_data) 
78 {
79     struct v3_privileges * privs = (struct v3_privileges *)priv_data;
80     struct v3_priv * p = NULL;
81     struct v3_priv * tmp = NULL;
82
83     list_for_each_entry_safe(p, tmp, &(privs->priv_list), priv_node) {
84         list_del(&(p->priv_node));
85         V3_Free(p);
86     }
87
88     v3_free_htable(privs->priv_table, 0, 0);
89
90     return 0;
91 }
92
93
94 struct v3_priv * 
95 v3_lookup_priv (struct v3_vm_info * vm, const char * name) 
96 {
97     struct v3_privileges * p = global_privs;
98     return ((struct v3_priv*)v3_htable_search(p->priv_table, (addr_t)name));
99 }
100
101
102 static int 
103 deinit_all_privs (struct guest_info * core, 
104                      void * priv_data,
105                      void * core_data) 
106 {
107     struct v3_privileges * p = global_privs;
108     struct v3_priv * priv = NULL;
109     struct v3_priv * tmp = NULL;
110
111     list_for_each_entry_safe(priv, tmp, &p->priv_list, priv_node) {
112         if (priv->deinit(core, priv->private_data) < 0) {
113             PrintError(VM_NONE, VCORE_NONE,"Problem deiniting privilege on core (%s)\n", priv->name);
114         }
115     }
116
117     return 0;
118 }
119
120
121 int 
122 v3_core_raise_all_privs (struct guest_info * core)
123 {
124     struct v3_privileges * p = global_privs;
125     struct v3_priv * priv = NULL;
126     struct v3_priv * tmp = NULL;
127
128     list_for_each_entry_safe(priv, tmp, &p->priv_list, priv_node) {
129     
130         if (priv->raise(core, priv->private_data) < 0) {
131             PrintError(VM_NONE, VCORE_NONE,"Priv: Problem lowering privilege on core (%s)\n", priv->name);
132             return -1;
133         }
134
135     }
136
137     return 0;
138 }
139
140
141 int 
142 v3_core_lower_all_privs (struct guest_info * core) 
143 {
144     struct v3_privileges * p = global_privs;
145     struct v3_priv * priv = NULL;
146     struct v3_priv * tmp = NULL;
147
148     list_for_each_entry_safe(priv, tmp, &p->priv_list, priv_node) {
149         
150         if (priv->lower(core, priv->private_data) < 0) {
151             PrintError(VM_NONE, VCORE_NONE,"Priv: Problem lowering privilege on core (%s)\n", priv->name);
152             return -1;
153         }
154
155     }
156
157     return 0;
158 }
159
160
161 int 
162 v3_bind_privilege (struct guest_info * core,
163                    const char * priv_name,
164                    int (*init)   (struct guest_info * core, void ** private_data),
165                    int (*lower)  (struct guest_info * core, void * private_data),
166                    int (*raise)  (struct guest_info * core, void * private_data),
167                    int (*deinit) (struct guest_info * core, void * private_data),
168                    void * priv_data)
169 {
170     struct v3_privileges * p = global_privs;
171     struct v3_priv * priv = v3_lookup_priv(core->vm_info, priv_name);
172     if (priv) {
173         PrintError(VM_NONE, VCORE_NONE,"Priv: Privilege (%s) already exists\n", priv_name);
174         return -1;
175     }
176
177     priv = (struct v3_priv *)V3_Malloc(sizeof(struct v3_priv));
178     
179     if (!priv) {
180         PrintError(VM_NONE, VCORE_NONE,"Priv: Problem allocating privilege\n");
181         return -1;
182     }
183
184     PrintDebug(VM_NONE, VCORE_NONE,"Priv: Binding privilege (%s)\n", priv_name);
185
186     priv->init         = init;
187     priv->lower        = lower;
188     priv->raise        = raise;
189     priv->deinit       = deinit;
190     priv->private_data = priv_data;
191
192     if (v3_htable_insert(p->priv_table, (addr_t)priv_name, (addr_t)priv) == 0) {
193         PrintError(VM_NONE, VCORE_NONE,"Priv: Could not register privilege (%s)\n", priv_name);
194         return -1;
195     }
196
197     if (priv->init(core, &priv->private_data) < 0) {
198         PrintError(VM_NONE, VCORE_NONE,"Priv: Could not initialize privilege (%s)\n", priv_name);
199         return -1;
200     }
201
202     V3_Print(VM_NONE, VCORE_NONE, "Privilege (%s) bound and initialized successfully\n", priv_name);
203
204     return 0;
205 }
206                             
207
208
209 static struct v3_extension_impl priv_impl = {
210         .name = "privilege",
211         .vm_init = init_priv,
212         .vm_deinit = deinit_priv,
213         .core_init = NULL,
214         .core_deinit = deinit_all_privs,
215         .on_entry = NULL,
216         .on_exit = NULL
217 };
218
219 register_extension(&priv_impl);