2 * Linux interface for guest-context code injection
4 * (c) Kyle C. Hale 2011
9 #include <linux/uaccess.h>
11 #include <linux/module.h>
13 #include <gears/code_inject.h>
17 #include "linux-exts.h"
18 #include "iface-code-inject.h"
21 /* eventually this should probably be a hash table,
22 * hashed on unique inject data
24 static struct top_half_data *top_map[MAX_INJ] = {[0 ... MAX_INJ - 1] = 0};
26 static int register_top(struct top_half_data *top) {
29 for (i = 0; i < MAX_INJ; i++) {
40 static void free_inject_data (void) {
43 for(i = 0; i < MAX_INJ; i++) {
45 palacios_free(top_map[i]->elf_data);
46 palacios_free(top_map[i]);
53 static int vm_tophalf_inject (struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) {
54 struct top_half_data top_arg;
55 struct top_half_data * top;
57 top = palacios_alloc(sizeof(struct top_half_data));
59 ERROR("Palacios Error: could not allocate space for top half data\n");
62 memset(top, 0, sizeof(struct top_half_data));
64 INFO("Palacios: Loading ELF data...\n");
65 if (copy_from_user(&top_arg, (void __user *)arg, sizeof(struct top_half_data))) {
66 ERROR("palacios: error copying ELF from userspace\n");
71 top->elf_size = top_arg.elf_size;
72 top->func_offset = top_arg.func_offset;
73 top->is_dyn = top_arg.is_dyn;
75 /* we have a binary name */
76 if (top_arg.is_exec_hooked) {
77 strcpy(top->bin_file, top_arg.bin_file);
78 top->is_exec_hooked = 1;
79 DEBUG("top->bin_file is %s\n", top->bin_file);
82 DEBUG("Palacios: Allocating %lu B of kernel memory for ELF binary data...\n", top->elf_size);
83 top->elf_data = palacios_alloc(top->elf_size);
84 if (!(top->elf_data)) {
85 ERROR("Palacios Error: could not allocate space for binary image\n");
89 memset(top->elf_data, 0, top->elf_size);
91 INFO("Palacios: Copying ELF image into kernel module...\n");
92 if (copy_from_user(top->elf_data, (void __user *)top_arg.elf_data, top->elf_size)) {
93 ERROR("Palacios: Error loading elf data\n");
94 palacios_free(top->elf_data);
99 if (register_top(top) < 0) {
100 ERROR("Cannot register top half\n");
101 palacios_free(top->elf_data);
106 INFO("Palacios: setting up inject code...\n");
107 if (v3_insert_code_inject(guest->v3_ctx, top->elf_data, top->elf_size,
108 top->bin_file, top->is_dyn, top->is_exec_hooked, top->func_offset) < 0) {
109 ERROR("Palacios Error: error setting up inject code\n");
110 palacios_free(top->elf_data);
115 INFO("Palacios: injection registration complete\n");
120 static int init_code_inject (void) {
125 static int deinit_code_inject (void) {
130 static int guest_init_code_inject (struct v3_guest * guest, void ** vm_data) {
131 add_guest_ctrl(guest, V3_VM_TOPHALF_INJECT, vm_tophalf_inject, NULL);
136 static int guest_deinit_code_inject (struct v3_guest * guest, void * vm_data) {
138 remove_guest_ctrl(guest, V3_VM_TOPHALF_INJECT);
143 static struct linux_ext code_inject_ext = {
144 .name = "CODE_INJECT",
145 .init = init_code_inject,
146 .deinit = deinit_code_inject,
147 .guest_init = guest_init_code_inject,
148 .guest_deinit = guest_deinit_code_inject
151 register_extension(&code_inject_ext);