palacios-vnet-ctrl.o \
palacios-vnet-brg.o
+v3vee-$(V3_CONFIG_HOST_HYPERCALL) += iface-host-hypercall.o
+v3vee-$(V3_CONFIG_EXT_CODE_INJECT) += iface-code-inject.o
+v3vee-$(V3_CONFIG_EXT_ENV_INJECT) += iface-env-inject.o
v3vee-objs := $(v3vee-y) ../libv3vee.a
obj-m := v3vee.o
--- /dev/null
+/*
+ * Linux interface for guest-context code injection
+ *
+ * (c) Kyle C. Hale 2011
+ *
+ */
+
+#include <linux/elf.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+#include <linux/module.h>
+
+#include <gears/code_inject.h>
+
+#include "palacios.h"
+#include "vm.h"
+#include "linux-exts.h"
+#include "iface-code-inject.h"
+
+
+/* eventually this should probably be a hash table,
+ * hashed on unique inject data
+ */
+static struct top_half_data *top_map[MAX_INJ] = {[0 ... MAX_INJ - 1] = 0};
+
+static int register_top(struct top_half_data *top) {
+ int i;
+
+ for (i = 0; i < MAX_INJ; i++) {
+ if (!top_map[i]) {
+ top_map[i] = top;
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+
+static void free_inject_data (void) {
+ int i;
+
+ for(i = 0; i < MAX_INJ; i++) {
+ if (top_map[i]) {
+ kfree(top_map[i]->elf_data);
+ kfree(top_map[i]);
+ }
+ }
+}
+
+
+
+static int vm_tophalf_inject (struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) {
+ struct top_half_data top_arg;
+ struct top_half_data * top;
+
+ top = kmalloc(sizeof(struct top_half_data), GFP_KERNEL);
+ if (IS_ERR(top)) {
+ printk("Palacios Error: could not allocate space for top half data\n");
+ return -EFAULT;
+ }
+ memset(top, 0, sizeof(struct top_half_data));
+
+ printk("Palacios: Loading ELF data...\n");
+ if (copy_from_user(&top_arg, (void __user *)arg, sizeof(struct top_half_data))) {
+ printk("palacios: error copying ELF from userspace\n");
+ return -EFAULT;
+ }
+
+ top->elf_size = top_arg.elf_size;
+ top->func_offset = top_arg.func_offset;
+ top->is_dyn = top_arg.is_dyn;
+
+ /* we have a binary name */
+ if (top_arg.is_exec_hooked) {
+ strcpy(top->bin_file, top_arg.bin_file);
+ top->is_exec_hooked = 1;
+ printk("top->bin_file is %s\n", top->bin_file);
+ }
+
+ printk("Palacios: Allocating %lu B of kernel memory for ELF binary data...\n", top->elf_size);
+ top->elf_data = kmalloc(top->elf_size, GFP_KERNEL);
+ if (IS_ERR(top->elf_data)) {
+ printk("Palacios Error: could not allocate space for binary image\n");
+ return -EFAULT;
+ }
+ memset(top->elf_data, 0, top->elf_size);
+
+ printk("Palacios: Copying ELF image into kernel module...\n");
+ if (copy_from_user(top->elf_data, (void __user *)top_arg.elf_data, top->elf_size)) {
+ printk("Palacios: Error loading elf data\n");
+ return -EFAULT;
+ }
+
+ if (register_top(top) < 0)
+ return -1;
+
+ printk("Palacios: setting up inject code...\n");
+ if (v3_insert_code_inject(guest->v3_ctx, top->elf_data, top->elf_size,
+ top->bin_file, top->is_dyn, top->is_exec_hooked, top->func_offset) < 0) {
+ printk("Palacios Error: error setting up inject code\n");
+ return -1;
+ }
+
+ printk("Palacios: injection registration complete\n");
+ return 0;
+}
+
+
+static int init_code_inject (void) {
+ return 0;
+}
+
+
+static int deinit_code_inject (void) {
+ return 0;
+}
+
+
+static int guest_init_code_inject (struct v3_guest * guest, void ** vm_data) {
+ add_guest_ctrl(guest, V3_VM_TOPHALF_INJECT, vm_tophalf_inject, NULL);
+ return 0;
+}
+
+
+static int guest_deinit_code_inject (struct v3_guest * guest, void * vm_data) {
+ free_inject_data();
+ return 0;
+}
+
+
+static struct linux_ext code_inject_ext = {
+ .name = "CODE_INJECT",
+ .init = init_code_inject,
+ .deinit = deinit_code_inject,
+ .guest_init = guest_init_code_inject,
+ .guest_deinit = guest_deinit_code_inject
+};
+
+register_extension(&code_inject_ext);
--- /dev/null
+#ifndef __IFACE_CODE_INJECT_H__
+#define __IFACE_CODE_INJECT_H__
+
+#define V3_VM_TOPHALF_INJECT 12123
+#define V3_VM_HYPERCALL_ADD 12124
+#define V3_VM_HYPERCALL_REMOVE 12125
+
+#define MAX_INJ 128
+
+struct top_half_data {
+ unsigned long elf_size;
+ void *elf_data;
+ int got_offset;
+ int plt_offset;
+ int func_offset;
+ char bin_file[256];
+ int hcall_nr;
+ int inject_id;
+ int is_dyn;
+ int is_exec_hooked;
+};
+
+#define HCALL_NAME_MAX 256
+
+struct hcall_data {
+ int fd;
+ int hcall_nr;
+ char fn[HCALL_NAME_MAX];
+};
+
+#endif
--- /dev/null
+/*
+ * Linux interface for guest-context environment variable injection
+ *
+ * (c) Kyle C. Hale 2012
+ *
+ */
+
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+#include <gears/env_inject.h>
+
+#include "palacios.h"
+#include "vm.h"
+#include "linux-exts.h"
+#include "iface-env-inject.h"
+
+
+static struct env_data * env_map[MAX_ENV_INJECT] = {[0 ... MAX_ENV_INJECT - 1] = 0};
+
+
+static int register_env(struct env_data * env) {
+ int i;
+
+ for (i = 0; i < MAX_ENV_INJECT; i++) {
+ if (!env_map[i]) {
+ env_map[i] = env;
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+static void free_inject_data (void) {
+ int i, j;
+
+ for(i = 0; i < MAX_ENV_INJECT; i++) {
+ if (env_map[i]) {
+ for (j = 0; j < env_map[i]->num_strings; j++)
+ kfree(env_map[i]->strings[j]);
+
+ kfree(env_map[i]->strings);
+ kfree(env_map[i]);
+ }
+ }
+}
+
+
+
+static int vm_env_inject (struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) {
+ struct env_data env_arg;
+ struct env_data * env;
+ int i;
+
+ printk("Palacios: Loading environment data...\n");
+ if (copy_from_user(&env_arg, (void __user *)arg, sizeof(struct env_data))) {
+ printk("palacios: error copying environment data from userspace\n");
+ return -EFAULT;
+ }
+
+ env = kmalloc(sizeof(struct env_data), GFP_KERNEL);
+ if (IS_ERR(env)) {
+ printk("Palacios Error: could not allocate space for environment data\n");
+ return -EFAULT;
+ }
+
+ memset(env, 0, sizeof(struct env_data));
+
+ env->num_strings = env_arg.num_strings;
+
+ strcpy(env->bin_name, env_arg.bin_name);
+ printk("Binary hooked on: %s\n", env->bin_name);
+
+ //printk("Palacios: Allocating space for %u env var string ptrs...\n", env->num_strings);
+ env->strings = kmalloc(env->num_strings*sizeof(char*), GFP_KERNEL);
+ if (IS_ERR(env->strings)) {
+ printk("Palacios Error: could not allocate space for env var strings\n");
+ return -EFAULT;
+ }
+ memset(env->strings, 0, env->num_strings*sizeof(char*));
+
+ //printk("Palacios: copying env var string pointers\n");
+ if (copy_from_user(env->strings, (void __user *)env_arg.strings, env->num_strings*sizeof(char*))) {
+ printk("Palacios: Error copying string pointers\n");
+ return -EFAULT;
+ }
+
+ for (i = 0; i < env->num_strings; i++) {
+ char * tmp = kmalloc(MAX_STRING_LEN, GFP_KERNEL);
+ if (IS_ERR(tmp)) {
+ printk("Palacios Error: could not allocate space for env var string #%d\n", i);
+ return -EFAULT;
+ }
+
+ if (copy_from_user(tmp, (void __user *)env->strings[i], MAX_STRING_LEN)) {
+ printk("Palacios: Error copying string #%d\n", i);
+ return -EFAULT;
+ }
+ env->strings[i] = tmp;
+ }
+
+ printk("Palacios: registering environment data...\n");
+ if (register_env(env) < 0)
+ return -1;
+
+ printk("Palacios: passing data off to palacios...\n");
+ if (v3_insert_env_inject(guest->v3_ctx, env->strings, env->num_strings, env->bin_name) < 0) {
+ printk("Palacios: Error passing off environment data\n");
+ return -1;
+ }
+
+ printk("Palacios: environment injection registration complete\n");
+ return 0;
+}
+
+
+static int init_env_inject (void) {
+ return 0;
+}
+
+
+static int deinit_env_inject (void) {
+ return 0;
+}
+
+
+static int guest_init_env_inject (struct v3_guest * guest, void ** vm_data) {
+ add_guest_ctrl(guest, V3_VM_ENV_INJECT, vm_env_inject, NULL);
+ return 0;
+}
+
+
+static int guest_deinit_env_inject (struct v3_guest * guest, void * vm_data) {
+ free_inject_data();
+ return 0;
+}
+
+
+static struct linux_ext env_inject_ext = {
+ .name = "ENV_INJECT",
+ .init = init_env_inject,
+ .deinit = deinit_env_inject,
+ .guest_init = guest_init_env_inject,
+ .guest_deinit = guest_deinit_env_inject
+};
+
+register_extension(&env_inject_ext);
--- /dev/null
+#ifndef __IFACE_ENV_INJECT_H__
+#define __IFACE_ENV_INJECT_H__
+
+
+#define MAX_NUM_STRINGS 10
+#define MAX_STRING_LEN 128
+#define MAX_ENV_INJECT 10
+
+#define V3_VM_ENV_INJECT 13125
+
+struct env_data {
+ int num_strings;
+ char ** strings;
+ char bin_name[MAX_STRING_LEN];
+};
+
+
+#endif
258 -- (IFACE) VGA Console Framebuf Query
10245 -- (IFACE) Connect Host Device
+
+12123 -- (EXT) Inject Top Half Code into Guest
+
+12124 -- (EXT) Register host hypercall (remember to insmod first)
+12124 -- (EXT) Unregister host hypercall
+
+13125 -- (EXT) Inject Environment Variables into Guest Process
+