direct-io.hg

view tools/libxc/xc_core.c @ 9145:9de50910defd

libxc: Verify Magic number when reading dump

The xen core files record a magic number,
but when they are loaded it isn't checked.
This patch resolves this.

Signed-Off-By: Horms <horms@verge.net.au>
author kaf24@firebug.cl.cam.ac.uk
date Mon Mar 06 15:04:18 2006 +0100 (2006-03-06)
parents 316fafc6d743
children 17e26f60e901
line source
1 #include "xg_private.h"
2 #define ELFSIZE 32
3 #include "xc_elf.h"
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <zlib.h>
8 /* number of pages to write at a time */
9 #define DUMP_INCREMENT 4 * 1024
10 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
12 static int
13 copy_from_domain_page(int xc_handle,
14 uint32_t domid,
15 unsigned long *page_array,
16 unsigned long src_pfn,
17 void *dst_page)
18 {
19 void *vaddr = xc_map_foreign_range(
20 xc_handle, domid, PAGE_SIZE, PROT_READ, page_array[src_pfn]);
21 if ( vaddr == NULL )
22 return -1;
23 memcpy(dst_page, vaddr, PAGE_SIZE);
24 munmap(vaddr, PAGE_SIZE);
25 return 0;
26 }
28 int
29 xc_domain_dumpcore(int xc_handle,
30 uint32_t domid,
31 const char *corename)
32 {
33 unsigned long nr_pages;
34 unsigned long *page_array;
35 xc_dominfo_t info;
36 int i, nr_vcpus = 0, dump_fd;
37 char *dump_mem, *dump_mem_start = NULL;
38 struct xc_core_header header;
39 vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
42 if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
43 PERROR("Could not open corefile %s: %s", corename, strerror(errno));
44 goto error_out;
45 }
47 if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) {
48 PERROR("Could not allocate dump_mem");
49 goto error_out;
50 }
52 if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {
53 PERROR("Could not get info for domain");
54 goto error_out;
55 }
57 for (i = 0; i < info.max_vcpu_id; i++)
58 if (xc_vcpu_getcontext(xc_handle, domid,
59 i, &ctxt[nr_vcpus]) == 0)
60 nr_vcpus++;
62 nr_pages = info.nr_pages;
64 header.xch_magic = XC_CORE_MAGIC;
65 header.xch_nr_vcpus = nr_vcpus;
66 header.xch_nr_pages = nr_pages;
67 header.xch_ctxt_offset = sizeof(struct xc_core_header);
68 header.xch_index_offset = sizeof(struct xc_core_header) +
69 sizeof(vcpu_guest_context_t)*nr_vcpus;
70 header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) +
71 (sizeof(vcpu_guest_context_t) * nr_vcpus) +
72 (nr_pages * sizeof(unsigned long)));
74 if (write(dump_fd, &header, sizeof(struct xc_core_header)) < 0 ||
75 write(dump_fd, &ctxt, sizeof(ctxt[0]) * nr_vcpus) < 0)
76 {
77 PERROR("write failed");
78 goto error_out;
79 }
81 if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
82 printf("Could not allocate memory\n");
83 goto error_out;
84 }
85 if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
86 printf("Could not get the page frame list\n");
87 goto error_out;
88 }
89 if (write(dump_fd, page_array, nr_pages * sizeof(unsigned long)) < 0)
90 {
91 PERROR("write failed");
92 goto error_out;
93 }
94 lseek(dump_fd, header.xch_pages_offset, SEEK_SET);
95 for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) {
96 copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem);
97 dump_mem += PAGE_SIZE;
98 if (((i + 1) % DUMP_INCREMENT == 0) || (i + 1) == nr_pages) {
99 if (write(dump_fd, dump_mem_start, dump_mem - dump_mem_start) <
100 dump_mem - dump_mem_start) {
101 PERROR("Partial write, file system full?");
102 goto error_out;
103 }
104 dump_mem = dump_mem_start;
105 }
106 }
108 close(dump_fd);
109 free(dump_mem_start);
110 return 0;
111 error_out:
112 if (dump_fd != -1)
113 close(dump_fd);
114 free(dump_mem_start);
115 return -1;
116 }
118 /*
119 * Local variables:
120 * mode: C
121 * c-set-style: "BSD"
122 * c-basic-offset: 4
123 * tab-width: 4
124 * indent-tabs-mode: nil
125 * End:
126 */