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 and sanity-checking of use of strncpy/strcpy (Coverity static analysis)
[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     strncpy(env->bin_name, env_arg.bin_name, MAX_STRING_LEN);
72     env->bin_name[MAX_STRING_LEN-1] = 0;
73     DEBUG("Binary hooked on: %s\n", env->bin_name);
74
75     //DEBUG("Palacios: Allocating space for %u env var string ptrs...\n", env->num_strings);
76     env->strings = palacios_alloc(env->num_strings*sizeof(char*));
77     if (!(env->strings)) {
78         ERROR("Palacios Error: could not allocate space for env var strings\n");
79         return -EFAULT;
80     }
81     memset(env->strings, 0, env->num_strings*sizeof(char*));
82
83     //INFO("Palacios: copying env var string pointers\n");
84     if (copy_from_user(env->strings, (void __user *)env_arg.strings, env->num_strings*sizeof(char*))) {
85         ERROR("Palacios: Error copying string pointers\n");
86         return -EFAULT;
87     }
88
89     for (i = 0; i < env->num_strings; i++) {
90         char * tmp  = palacios_alloc(MAX_STRING_LEN);
91         if (!(tmp)) {
92             ERROR("Palacios Error: could not allocate space for env var string #%d\n", i);
93             return -EFAULT;
94         }
95
96         if (copy_from_user(tmp, (void __user *)env->strings[i], MAX_STRING_LEN)) {
97             ERROR("Palacios: Error copying string #%d\n", i);
98             return -EFAULT;
99         }
100         env->strings[i] = tmp;
101     }
102
103     INFO("Palacios: registering environment data...\n");
104     if (register_env(env) < 0) 
105         return -1;
106     
107     DEBUG("Palacios: passing data off to palacios...\n");
108     if (v3_insert_env_inject(guest->v3_ctx, env->strings, env->num_strings, env->bin_name) < 0) {
109         ERROR("Palacios: Error passing off environment data\n");
110         return -1;
111     }
112
113     INFO("Palacios: environment injection registration complete\n");
114     return 0;
115 }
116
117
118 static int init_env_inject (void) {
119     return 0;
120 }
121
122
123 static int deinit_env_inject (void) {
124     return 0;
125 }
126
127
128 static int guest_init_env_inject (struct v3_guest * guest, void ** vm_data) {
129     add_guest_ctrl(guest, V3_VM_ENV_INJECT, vm_env_inject, NULL);
130     return 0;
131 }
132
133
134 static int guest_deinit_env_inject (struct v3_guest * guest, void * vm_data) {
135     free_inject_data();
136     remove_guest_ctrl(guest, V3_VM_ENV_INJECT);
137     return 0;
138 }
139
140
141 static struct linux_ext env_inject_ext = {
142     .name = "ENV_INJECT",
143     .init = init_env_inject,
144     .deinit = deinit_env_inject,
145     .guest_init = guest_init_env_inject,
146     .guest_deinit = guest_deinit_env_inject 
147 };
148
149 register_extension(&env_inject_ext);