Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Gears userspace utilities
Kyle Hale [Fri, 13 Apr 2012 21:52:34 +0000 (16:52 -0500)]
linux_usr/v3_env_inject.c [new file with mode: 0644]
linux_usr/v3_top_inject.c [new file with mode: 0644]

diff --git a/linux_usr/v3_env_inject.c b/linux_usr/v3_env_inject.c
new file mode 100644 (file)
index 0000000..466e8a5
--- /dev/null
@@ -0,0 +1,87 @@
+/* 
+ * V3 Environment Variable Injection Utility
+ * This code allows a user to inject environment variables into a process
+ * marked by a specific binary name in a running guest.
+ *
+ * (c) Kyle C. Hale, 2012
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "iface-env-inject.h"
+
+
+static void usage (char* bin) {
+       fprintf(stderr, "Usage: %s /dev/v3-vm<N> env-file inject-point-exe\n", bin);
+}
+
+int main (int argc, char **argv) {
+       char *vm_dev, *env_file, *bin_name;
+       int vm_fd, err, bytes_read, num_strings;
+    struct stat t_stat;
+    struct env_data env;
+    char * strings[MAX_NUM_STRINGS];
+    char tmp_str[MAX_STRING_LEN];
+    int i = 0;
+    FILE * t_fd;
+
+       if (argc < 4) {
+               usage(argv[0]);
+               return -1;
+       }
+
+       vm_dev = argv[1];
+    env_file = argv[2];
+    bin_name = argv[3];
+
+       t_fd = fopen(env_file, "r");
+       if (!t_fd) {
+               fprintf(stderr, "Error opening environment variable file: %s\n", env_file);
+               return -1;
+       }
+
+    /* copy in the vars line by line */
+    while (fgets(tmp_str, MAX_STRING_LEN, t_fd) != NULL) {
+        int len = strlen(tmp_str) - 1;
+        if (tmp_str[len] == '\n')
+            tmp_str[len] = 0;
+        strings[i] = (char*)malloc(MAX_STRING_LEN);
+        strcpy(strings[i], tmp_str);
+        i++;
+    }
+
+    env.num_strings = i;
+    printf("Found %d environment variables to inject\n", i);
+
+    env.strings = (char**) strings;
+
+    if (!bin_name) {
+        fprintf(stderr, "Error: no binary hook provided\n");
+        return -1;
+    }
+
+    strncpy(env.bin_name, bin_name, MAX_STRING_LEN);
+
+       vm_fd = open(vm_dev, O_RDONLY);
+       if (vm_fd == -1) {
+               fprintf(stderr, "Error opening VM device: %s\n", vm_dev);
+               return -1;
+       }
+
+    printf("Transferring control to Palacios\n");
+       err = ioctl(vm_fd, V3_VM_ENV_INJECT, &env);
+       if (err < 0) {
+               fprintf(stderr, "Error providing env var data to palacios\n");
+               return -1;
+       }
+    
+       close(t_fd);
+       close(vm_fd);
+       return 0;
+}
diff --git a/linux_usr/v3_top_inject.c b/linux_usr/v3_top_inject.c
new file mode 100644 (file)
index 0000000..2e59202
--- /dev/null
@@ -0,0 +1,150 @@
+/* 
+ * V3 Top Half Injection Utility
+ * This code allows a user to inject a "top half" of code into a running guest. 
+ * The "bottom half" (a hypercall handler) is inserted using another utility.
+ *
+ * (c) Kyle C. Hale, 2011
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include <elf.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "iface-code-inject.h"
+
+#define __ELF_INJECT_CLASS 32
+
+#define ElfW(type)     _ElfW (Elf, __ELF_INJECT_CLASS, type)
+#define _ElfW(e,w,t)   _ElfW_1 (e, w, _##t)
+#define _ElfW_1(e,w,t) e##w##t
+
+
+static void usage (char* bin) {
+       fprintf(stderr, "Usage: %s /dev/v3-vm<N> <inject-code> <code-entry-offset> [inject-point-exe]\n", bin);
+}
+
+
+/* look for PT_DYNAMIC to see if it's dynamically linked */
+static int is_dynamic (ElfW(Ehdr) * ehdr) {
+    int i;
+    ElfW(Phdr) * phdr = (ElfW(Phdr)*)((char*)ehdr + ehdr->e_phoff);
+    ElfW(Phdr) * phdr_cursor;
+
+    phdr_cursor = phdr;
+
+    for (i = 0; i < ehdr->e_phnum; i++, phdr_cursor++) {
+        if (phdr_cursor->p_type == PT_DYNAMIC)
+            return 1;
+    }
+
+    return 0;
+}
+
+
+int main (int argc, char **argv) {
+       char *vm_dev = NULL;
+       char *top_half = NULL;
+    char *bin_file = NULL;
+       int vm_fd, t_fd, err, bytes_read, entry;
+    struct stat t_stat;
+    struct top_half_data elf;
+    ElfW(Ehdr) * elf_hdr;
+
+       if (argc < 4 || argc > 5) {
+               usage(argv[0]);
+               return -1;
+       }
+
+       vm_dev = argv[1];
+    top_half = argv[2];
+    entry = strtol(argv[3], NULL, 0);
+    if (argv[4]) 
+        bin_file = argv[4];
+    
+
+       t_fd = open(top_half, O_RDONLY);
+       if (t_fd == -1) {
+               fprintf(stderr, "Error opening top half .o file: %s\n", top_half);
+               return -1;
+       }
+
+    if (fstat(t_fd, &t_stat) < 0) {
+        fprintf(stderr, "Error: could not stat ELF binary file %s\n", top_half);
+        return -1;
+    }
+
+    memset(&elf, 0, sizeof(struct top_half_data));
+
+    elf.elf_size = t_stat.st_size;
+
+    if (bin_file) {
+        strcpy(elf.bin_file, bin_file);
+        elf.is_exec_hooked = 1;
+    } else {
+        elf.is_exec_hooked = 0;
+    }
+
+        
+    /* read in the ELF */
+    elf.elf_data = malloc(elf.elf_size);
+    if (!elf.elf_data) {
+        fprintf(stderr, "Error allocating memory for ELF data\n");
+        return -1;
+    }
+
+    printf("Loading ELF binary...\n");
+    if ((bytes_read = read(t_fd, elf.elf_data, elf.elf_size)) < 0) {
+        fprintf(stderr, "Error loading ELF binary %s\n", top_half);
+        return -1;
+    }
+
+    printf("Loaded. %d Bytes of data read\n", bytes_read);
+    elf_hdr = (ElfW(Ehdr)*)elf.elf_data;
+
+    /* set the entry point */
+    elf.func_offset = entry;
+
+    /* check the ELF magic nr to make sure this is a valid ELF */
+    if (elf_hdr->e_ident[EI_MAG0] != 0x7f ||
+        elf_hdr->e_ident[EI_MAG1] != 'E'  ||
+        elf_hdr->e_ident[EI_MAG2] != 'L'  ||
+        elf_hdr->e_ident[EI_MAG3] != 'F') {
+            
+        fprintf(stderr, "Error: Invalid ELF binary %s\n", top_half);
+        return -1;
+    }
+
+    /* make sure the ELF is an actual executable file */
+    if (elf_hdr->e_type != ET_EXEC) {
+        fprintf(stderr, "Error: ELF must be an executable file %s\n", top_half);
+        return -1;
+    }
+
+    /* is it a dynamically linked executable? */
+    elf.is_dyn = is_dynamic(elf_hdr);
+
+       vm_fd = open(vm_dev, O_RDONLY);
+       if (vm_fd == -1) {
+               fprintf(stderr, "Error opening VM device: %s\n", vm_dev);
+               return -1;
+       }
+
+    printf("Transferring control to Palacios\n");
+       err = ioctl(vm_fd, V3_VM_TOPHALF_INJECT, &elf);
+       if (err < 0) {
+               fprintf(stderr, "Error providing top half to palacios: %s\n", top_half);
+               return -1;
+       }
+    
+    free(elf.elf_data);
+       close(t_fd);
+       close(vm_fd);
+
+       return 0;
+}