2 * Linux interface for guest-context environment variable injection
4 * (c) Kyle C. Hale 2012
8 #include <linux/uaccess.h>
10 #include <gears/env_inject.h>
14 #include "linux-exts.h"
15 #include "iface-env-inject.h"
18 static struct env_data * env_map[MAX_ENV_INJECT] = {[0 ... MAX_ENV_INJECT - 1] = 0};
21 static int register_env(struct env_data * env) {
24 for (i = 0; i < MAX_ENV_INJECT; i++) {
34 static void free_inject_data (void) {
37 for(i = 0; i < MAX_ENV_INJECT; i++) {
39 for (j = 0; j < env_map[i]->num_strings; j++) {
40 palacios_free(env_map[i]->strings[j]);
42 palacios_free(env_map[i]->strings);
43 palacios_free(env_map[i]);
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;
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");
61 env = palacios_alloc(sizeof(struct env_data));
63 ERROR("Palacios Error: could not allocate space for environment data\n");
67 memset(env, 0, sizeof(struct env_data));
69 env->num_strings = env_arg.num_strings;
71 strcpy(env->bin_name, env_arg.bin_name);
72 DEBUG("Binary hooked on: %s\n", env->bin_name);
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");
80 memset(env->strings, 0, env->num_strings*sizeof(char*));
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");
88 for (i = 0; i < env->num_strings; i++) {
89 char * tmp = palacios_alloc(MAX_STRING_LEN);
91 ERROR("Palacios Error: could not allocate space for env var string #%d\n", i);
95 if (copy_from_user(tmp, (void __user *)env->strings[i], MAX_STRING_LEN)) {
96 ERROR("Palacios: Error copying string #%d\n", i);
99 env->strings[i] = tmp;
102 INFO("Palacios: registering environment data...\n");
103 if (register_env(env) < 0)
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");
112 INFO("Palacios: environment injection registration complete\n");
117 static int init_env_inject (void) {
122 static int deinit_env_inject (void) {
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);
133 static int guest_deinit_env_inject (struct v3_guest * guest, void * vm_data) {
135 remove_guest_ctrl(guest, V3_VM_ENV_INJECT);
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
148 register_extension(&env_inject_ext);