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.


af8ff6d3f072a7fbc3206d85c02c4ec320dac596
[palacios.git] / linux_module / iface-env-inject.c
1 /* 
2  * Linux interface for guest-context environment variable injection
3  *
4  * (c) Kyle C. Hale 2012
5  *
6  */
7
8 #include <linux/uaccess.h>
9
10 #include <gears/env_inject.h>
11
12 #include "palacios.h"
13 #include "vm.h"
14 #include "linux-exts.h"
15 #include "iface-env-inject.h"
16
17
18 static struct env_data * env_map[MAX_ENV_INJECT] = {[0 ... MAX_ENV_INJECT - 1] = 0};
19
20
21 static int register_env(struct env_data * env) {
22     int i;
23
24     for (i = 0; i < MAX_ENV_INJECT; i++) {
25         if (!env_map[i]) {
26             env_map[i] = env;
27             return i;
28         }
29     }
30     return -1;
31 }
32
33
34 static void free_inject_data (void) {
35     int i, j;
36
37     for(i = 0; i < MAX_ENV_INJECT; i++) {
38         if (env_map[i]) {
39             for (j = 0; j < env_map[i]->num_strings; j++) {
40                 palacios_free(env_map[i]->strings[j]);
41             }
42             palacios_free(env_map[i]->strings);
43             palacios_free(env_map[i]);
44         }
45     }
46 }
47
48
49
50 static int vm_env_inject (struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) {
51     struct env_data env_arg;
52     struct env_data * env;
53     int i;
54
55     INFO("Palacios: Loading environment data...\n");
56     if (copy_from_user(&env_arg, (void __user *)arg, sizeof(struct env_data))) {
57         ERROR("palacios: error copying environment data from userspace\n");
58         return -EFAULT;
59     }
60
61     env = palacios_alloc(sizeof(struct env_data));
62     if (!env) {
63         ERROR("Palacios Error: could not allocate space for environment data\n");
64         return -EFAULT;
65     }
66
67     memset(env, 0, sizeof(struct env_data));
68
69     env->num_strings = env_arg.num_strings;
70     
71     strcpy(env->bin_name, env_arg.bin_name);
72     DEBUG("Binary hooked on: %s\n", env->bin_name);
73
74     //DEBUG("Palacios: Allocating space for %u env var string ptrs...\n", env->num_strings);
75     env->strings = palacios_alloc(env->num_strings*sizeof(char*));
76     if (!(env->strings)) {
77         ERROR("Palacios Error: could not allocate space for env var strings\n");
78         return -EFAULT;
79     }
80     memset(env->strings, 0, env->num_strings*sizeof(char*));
81
82     //INFO("Palacios: copying env var string pointers\n");
83     if (copy_from_user(env->strings, (void __user *)env_arg.strings, env->num_strings*sizeof(char*))) {
84         ERROR("Palacios: Error copying string pointers\n");
85         return -EFAULT;
86     }
87
88     for (i = 0; i < env->num_strings; i++) {
89         char * tmp  = palacios_alloc(MAX_STRING_LEN);
90         if (!(tmp)) {
91             ERROR("Palacios Error: could not allocate space for env var string #%d\n", i);
92             return -EFAULT;
93         }
94
95         if (copy_from_user(tmp, (void __user *)env->strings[i], MAX_STRING_LEN)) {
96             ERROR("Palacios: Error copying string #%d\n", i);
97             return -EFAULT;
98         }
99         env->strings[i] = tmp;
100     }
101
102     INFO("Palacios: registering environment data...\n");
103     if (register_env(env) < 0) 
104         return -1;
105     
106     DEBUG("Palacios: passing data off to palacios...\n");
107     if (v3_insert_env_inject(guest->v3_ctx, env->strings, env->num_strings, env->bin_name) < 0) {
108         ERROR("Palacios: Error passing off environment data\n");
109         return -1;
110     }
111
112     INFO("Palacios: environment injection registration complete\n");
113     return 0;
114 }
115
116
117 static int init_env_inject (void) {
118     return 0;
119 }
120
121
122 static int deinit_env_inject (void) {
123     return 0;
124 }
125
126
127 static int guest_init_env_inject (struct v3_guest * guest, void ** vm_data) {
128     add_guest_ctrl(guest, V3_VM_ENV_INJECT, vm_env_inject, NULL);
129     return 0;
130 }
131
132
133 static int guest_deinit_env_inject (struct v3_guest * guest, void * vm_data) {
134     free_inject_data();
135     remove_guest_ctrl(guest, V3_VM_ENV_INJECT);
136     return 0;
137 }
138
139
140 static struct linux_ext env_inject_ext = {
141     .name = "ENV_INJECT",
142     .init = init_env_inject,
143     .deinit = deinit_env_inject,
144     .guest_init = guest_init_env_inject,
145     .guest_deinit = guest_deinit_env_inject 
146 };
147
148 register_extension(&env_inject_ext);