2 * Linux interface for guest-context environment variable injection
4 * (c) Kyle C. Hale 2012
8 #include <linux/uaccess.h>
9 #include <linux/vmalloc.h>
11 #include <gears/env_inject.h>
15 #include "linux-exts.h"
16 #include "iface-env-inject.h"
19 static struct env_data * env_map[MAX_ENV_INJECT] = {[0 ... MAX_ENV_INJECT - 1] = 0};
22 static int register_env(struct env_data * env) {
25 for (i = 0; i < MAX_ENV_INJECT; i++) {
35 static void free_inject_data (void) {
38 for(i = 0; i < MAX_ENV_INJECT; i++) {
40 for (j = 0; j < env_map[i]->num_strings; j++)
41 kfree(env_map[i]->strings[j]);
43 kfree(env_map[i]->strings);
51 static int vm_env_inject (struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) {
52 struct env_data env_arg;
53 struct env_data * env;
56 INFO("Palacios: Loading environment data...\n");
57 if (copy_from_user(&env_arg, (void __user *)arg, sizeof(struct env_data))) {
58 ERROR("palacios: error copying environment data from userspace\n");
62 env = kmalloc(sizeof(struct env_data), GFP_KERNEL);
64 ERROR("Palacios Error: could not allocate space for environment data\n");
68 memset(env, 0, sizeof(struct env_data));
70 env->num_strings = env_arg.num_strings;
72 strcpy(env->bin_name, env_arg.bin_name);
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 = kmalloc(env->num_strings*sizeof(char*), GFP_KERNEL);
77 if (IS_ERR(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 = kmalloc(MAX_STRING_LEN, GFP_KERNEL);
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) {
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);