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.


Cleaned up help messages for userspace utils
[palacios.git] / linux_usr / v3_top_inject.c
1 /* 
2  * V3 Top Half Injection Utility
3  * This code allows a user to inject a "top half" of code into a running guest. 
4  * The "bottom half" (a hypercall handler) is inserted using another utility.
5  *
6  * (c) Kyle C. Hale, 2011
7  */
8
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <malloc.h>
12 #include <string.h>
13 #include <elf.h>
14 #include <fcntl.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <sys/ioctl.h>
18
19 #include "iface-code-inject.h"
20
21 #define __ELF_INJECT_CLASS 32
22
23 #define ElfW(type)      _ElfW (Elf, __ELF_INJECT_CLASS, type)
24 #define _ElfW(e,w,t)    _ElfW_1 (e, w, _##t)
25 #define _ElfW_1(e,w,t)  e##w##t
26
27
28 static void usage (char* bin) {
29         fprintf(stderr, "usage: %s /dev/v3-vm<N> <inject-code> <code-entry-offset> [inject-point-exe]\n", bin);
30 }
31
32
33 /* look for PT_DYNAMIC to see if it's dynamically linked */
34 static int is_dynamic (ElfW(Ehdr) * ehdr) {
35     int i;
36     ElfW(Phdr) * phdr = (ElfW(Phdr)*)((char*)ehdr + ehdr->e_phoff);
37     ElfW(Phdr) * phdr_cursor;
38
39     phdr_cursor = phdr;
40
41     for (i = 0; i < ehdr->e_phnum; i++, phdr_cursor++) {
42         if (phdr_cursor->p_type == PT_DYNAMIC)
43             return 1;
44     }
45
46     return 0;
47 }
48
49
50 int main (int argc, char **argv) {
51         char *vm_dev = NULL;
52         char *top_half = NULL;
53     char *bin_file = NULL;
54         int vm_fd, t_fd, err, bytes_read, entry;
55     struct stat t_stat;
56     struct top_half_data elf;
57     ElfW(Ehdr) * elf_hdr;
58
59         if (argc < 4 || argc > 5) {
60                 usage(argv[0]);
61                 return -1;
62         }
63
64         vm_dev = argv[1];
65     top_half = argv[2];
66     entry = strtol(argv[3], NULL, 0);
67     if (argv[4]) 
68         bin_file = argv[4];
69     
70
71         t_fd = open(top_half, O_RDONLY);
72         if (t_fd == -1) {
73                 fprintf(stderr, "Error opening top half .o file: %s\n", top_half);
74                 return -1;
75         }
76
77     if (fstat(t_fd, &t_stat) < 0) {
78         fprintf(stderr, "Error: could not stat ELF binary file %s\n", top_half);
79         return -1;
80     }
81
82     memset(&elf, 0, sizeof(struct top_half_data));
83
84     elf.elf_size = t_stat.st_size;
85
86     if (bin_file) {
87         strcpy(elf.bin_file, bin_file);
88         elf.is_exec_hooked = 1;
89     } else {
90         elf.is_exec_hooked = 0;
91     }
92
93         
94     /* read in the ELF */
95     elf.elf_data = malloc(elf.elf_size);
96     if (!elf.elf_data) {
97         fprintf(stderr, "Error allocating memory for ELF data\n");
98         return -1;
99     }
100
101     printf("Loading ELF binary...\n");
102     if ((bytes_read = read(t_fd, elf.elf_data, elf.elf_size)) < 0) {
103         fprintf(stderr, "Error loading ELF binary %s\n", top_half);
104         return -1;
105     }
106
107     printf("Loaded. %d Bytes of data read\n", bytes_read);
108     elf_hdr = (ElfW(Ehdr)*)elf.elf_data;
109
110     /* set the entry point */
111     elf.func_offset = entry;
112
113     /* check the ELF magic nr to make sure this is a valid ELF */
114     if (elf_hdr->e_ident[EI_MAG0] != 0x7f ||
115         elf_hdr->e_ident[EI_MAG1] != 'E'  ||
116         elf_hdr->e_ident[EI_MAG2] != 'L'  ||
117         elf_hdr->e_ident[EI_MAG3] != 'F') {
118             
119         fprintf(stderr, "Error: Invalid ELF binary %s\n", top_half);
120         return -1;
121     }
122
123     /* make sure the ELF is an actual executable file */
124     if (elf_hdr->e_type != ET_EXEC) {
125         fprintf(stderr, "Error: ELF must be an executable file %s\n", top_half);
126         return -1;
127     }
128
129     /* is it a dynamically linked executable? */
130     elf.is_dyn = is_dynamic(elf_hdr);
131
132         vm_fd = open(vm_dev, O_RDONLY);
133         if (vm_fd == -1) {
134                 fprintf(stderr, "Error opening VM device: %s\n", vm_dev);
135                 return -1;
136         }
137
138     printf("Transferring control to Palacios\n");
139         err = ioctl(vm_fd, V3_VM_TOPHALF_INJECT, &elf);
140         if (err < 0) {
141                 fprintf(stderr, "Error providing top half to palacios: %s\n", top_half);
142                 return -1;
143         }
144     
145     free(elf.elf_data);
146         close(t_fd);
147         close(vm_fd);
148
149         return 0;
150 }