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 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);
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");
81 memset(env->strings, 0, env->num_strings*sizeof(char*));
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");
89 for (i = 0; i < env->num_strings; i++) {
90 char * tmp = palacios_alloc(MAX_STRING_LEN);
92 ERROR("Palacios Error: could not allocate space for env var string #%d\n", i);
96 if (copy_from_user(tmp, (void __user *)env->strings[i], MAX_STRING_LEN)) {
97 ERROR("Palacios: Error copying string #%d\n", i);
100 env->strings[i] = tmp;
103 INFO("Palacios: registering environment data...\n");
104 if (register_env(env) < 0)
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");
113 INFO("Palacios: environment injection registration complete\n");
118 static int init_env_inject (void) {
123 static int deinit_env_inject (void) {
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);
134 static int guest_deinit_env_inject (struct v3_guest * guest, void * vm_data) {
136 remove_guest_ctrl(guest, V3_VM_ENV_INJECT);
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
149 register_extension(&env_inject_ext);