debuggers.hg

view tools/libxl/libxl_exec.c @ 22855:1d1eec7e1fb4

xl: Perform minimal validation of virtual disk file while parsing config file

This patch performs some very basic validation on the virtual disk
file passed through the config file. This validation ensures that we
don't go too far with the initialization like spawn qemu and more
while there could be some potentially fundamental issues.

[ Patch fixed up to work with PHYSTYPE_EMPTY 22808:6ec61438713a -iwj ]

Signed-off-by: Kamala Narasimhan <kamala.narasimhan@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Kamala Narasimhan <kamala.narasimhan@gmail.com>
date Tue Jan 25 18:09:49 2011 +0000 (2011-01-25)
parents ca75ceb02221
children
line source
2 /*
3 * Copyright (C) 2009 Citrix Ltd.
4 * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
5 * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 only. with the special
10 * exception on linking described in file LICENSE.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 */
18 #include "libxl_osdeps.h"
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <assert.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <signal.h> /* for SIGKILL */
30 #include "libxl.h"
31 #include "libxl_internal.h"
33 static int call_waitpid(pid_t (*waitpid_cb)(pid_t, int *, int), pid_t pid, int *status, int options)
34 {
35 return (waitpid_cb) ? waitpid_cb(pid, status, options) : waitpid(pid, status, options);
36 }
38 void libxl__exec(int stdinfd, int stdoutfd, int stderrfd, const char *arg0,
39 char **args)
40 /* call this in the child */
41 {
42 int i;
44 if (stdinfd != -1)
45 dup2(stdinfd, STDIN_FILENO);
46 if (stdoutfd != -1)
47 dup2(stdoutfd, STDOUT_FILENO);
48 if (stderrfd != -1)
49 dup2(stderrfd, STDERR_FILENO);
50 for (i = 4; i < 256; i++)
51 close(i);
53 signal(SIGPIPE, SIG_DFL);
54 /* in case our caller set it to IGN. subprocesses are entitled
55 * to assume they got DFL. */
57 execvp(arg0, args);
58 _exit(-1);
59 }
61 void libxl_report_child_exitstatus(libxl_ctx *ctx,
62 xentoollog_level level,
63 const char *what, pid_t pid, int status)
64 {
66 if (WIFEXITED(status)) {
67 int st = WEXITSTATUS(status);
68 if (st)
69 LIBXL__LOG(ctx, level, "%s [%ld] exited"
70 " with error status %d", what, (unsigned long)pid, st);
71 else
72 LIBXL__LOG(ctx, level, "%s [%ld] unexpectedly"
73 " exited status zero", what, (unsigned long)pid);
74 } else if (WIFSIGNALED(status)) {
75 int sig = WTERMSIG(status);
76 const char *str = strsignal(sig);
77 const char *coredump = WCOREDUMP(status) ? " (core dumped)" : "";
78 if (str)
79 LIBXL__LOG(ctx, level, "%s [%ld] died due to"
80 " fatal signal %s%s", what, (unsigned long)pid,
81 str, coredump);
82 else
83 LIBXL__LOG(ctx, level, "%s [%ld] died due to unknown"
84 " fatal signal number %d%s", what, (unsigned long)pid,
85 sig, coredump);
86 } else {
87 LIBXL__LOG(ctx, level, "%s [%ld] gave unknown"
88 " wait status 0x%x", what, (unsigned long)pid, status);
89 }
90 }
92 int libxl__spawn_spawn(libxl_ctx *ctx,
93 libxl__device_model_starting *starting,
94 const char *what,
95 void (*intermediate_hook)(void *for_spawn,
96 pid_t innerchild))
97 {
98 pid_t child, got;
99 int status;
100 pid_t intermediate;
101 libxl__spawn_starting *for_spawn = starting->for_spawn;
103 if (for_spawn) {
104 for_spawn->what = strdup(what);
105 if (!for_spawn->what) return ERROR_NOMEM;
106 }
108 intermediate = libxl_fork(ctx);
109 if (intermediate ==-1) {
110 if (for_spawn) free(for_spawn->what);
111 return ERROR_FAIL;
112 }
113 if (intermediate) {
114 /* parent */
115 if (for_spawn) for_spawn->intermediate = intermediate;
116 return 1;
117 }
119 /* we are now the intermediate process */
121 child = fork();
122 if (child == -1)
123 exit(255);
124 if (!child)
125 return 0; /* caller runs child code */
127 intermediate_hook(starting, child);
129 if (!for_spawn) _exit(0); /* just detach then */
131 got = call_waitpid(ctx->waitpid_instead, child, &status, 0);
132 assert(got == child);
134 _exit(WIFEXITED(status) ? WEXITSTATUS(status) :
135 WIFSIGNALED(status) && WTERMSIG(status) < 127
136 ? WTERMSIG(status)+128 : -1);
137 }
139 static void report_spawn_intermediate_status(libxl_ctx *ctx,
140 libxl__spawn_starting *for_spawn,
141 int status)
142 {
143 if (!WIFEXITED(status)) {
144 char *intermediate_what;
145 /* intermediate process did the logging itself if it exited */
146 if ( asprintf(&intermediate_what,
147 "%s intermediate process (startup monitor)",
148 for_spawn->what) < 0 )
149 intermediate_what = "intermediate process (startup monitor)";
150 libxl_report_child_exitstatus(ctx, LIBXL__LOG_ERROR, intermediate_what,
151 for_spawn->intermediate, status);
152 }
153 }
155 int libxl__spawn_detach(libxl_ctx *ctx,
156 libxl__spawn_starting *for_spawn)
157 {
158 int r, status;
159 pid_t got;
160 int rc = 0;
162 if (!for_spawn) return 0;
164 if (for_spawn->intermediate) {
165 r = kill(for_spawn->intermediate, SIGKILL);
166 if (r) {
167 LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
168 "could not kill %s intermediate process [%ld]",
169 for_spawn->what,
170 (unsigned long)for_spawn->intermediate);
171 abort(); /* things are very wrong */
172 }
173 got = call_waitpid(ctx->waitpid_instead, for_spawn->intermediate, &status, 0);
174 assert(got == for_spawn->intermediate);
175 if (!(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)) {
176 report_spawn_intermediate_status(ctx, for_spawn, status);
177 rc = ERROR_FAIL;
178 }
179 for_spawn->intermediate = 0;
180 }
182 free(for_spawn->what);
183 for_spawn->what = 0;
185 return rc;
186 }
188 int libxl__spawn_check(libxl_ctx *ctx, void *for_spawn_void)
189 {
190 libxl__spawn_starting *for_spawn = for_spawn_void;
191 pid_t got;
192 int status;
194 if (!for_spawn) return 0;
196 assert(for_spawn->intermediate);
197 got = call_waitpid(ctx->waitpid_instead, for_spawn->intermediate, &status, WNOHANG);
198 if (!got) return 0;
200 assert(got == for_spawn->intermediate);
201 report_spawn_intermediate_status(ctx, for_spawn, status);
203 for_spawn->intermediate = 0;
204 return ERROR_FAIL;
205 }