mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
lxc: Don't pass a local variable address randomly
So, recently I was testing the LXC driver. You know, startup some
domains. But to my surprise, I was not able to start a single one:
virsh # start --console test
error: Reconnected to the hypervisor
error: Failed to start domain test
error: internal error: guest failed to start: unexpected exit status 125
So I've start digging. It turns out, that in virExec(), when I printed
out the @cmd, I got strange values: *(cmd->outfdptr) was certainly not
valid FD number: it has random value of several millions. This
obviously made prepareStdFd(childout, STDOUT_FILENO) fail (line 611).
But outfdptr is set in virCommandSetOutputFD(). The only place within
LXC driver where the function is called is in
virLXCProcessBuildControllerCmd(). If you take a closer look at the
function it looks like this:
static virCommandPtr
virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
..
int logfd,
const char *pidfile)
{
...
virCommandSetOutputFD(cmd, &logfd);
virCommandSetErrorFD(cmd, &logfd);
...
}
Yes, you guessed it. @logfd is passed into the function by value.
However, in the function we try to get its address (an address of a
local variable) which is no longer valid once function is finished and
stack is cleaned. Therefore when cmd->outfdptr is evaluated at any
point after this function, we may get a random number, depending on
what's currently on the stack. Of course, this may work sometimes too
- it depends on the compiler how it arranges the code, when the stack
is wiped out.
In order to fix this, lets pass a pointer to @logfd instead of
figuring out (wrong) its value in a function.
The bug was introduced in e1de5521
.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
ebd62ebaaa
commit
302146b16d
@ -750,7 +750,7 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
|
||||
int *files,
|
||||
size_t nfiles,
|
||||
int handshakefd,
|
||||
int logfd,
|
||||
int * const logfd,
|
||||
const char *pidfile)
|
||||
{
|
||||
size_t i;
|
||||
@ -820,8 +820,8 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
|
||||
virCommandPassFD(cmd, handshakefd, 0);
|
||||
virCommandDaemonize(cmd);
|
||||
virCommandSetPidFile(cmd, pidfile);
|
||||
virCommandSetOutputFD(cmd, &logfd);
|
||||
virCommandSetErrorFD(cmd, &logfd);
|
||||
virCommandSetOutputFD(cmd, logfd);
|
||||
virCommandSetErrorFD(cmd, logfd);
|
||||
/* So we can pause before exec'ing the controller to
|
||||
* write the live domain status XML with the PID */
|
||||
virCommandRequireHandshake(cmd);
|
||||
@ -1208,7 +1208,7 @@ int virLXCProcessStart(virConnectPtr conn,
|
||||
ttyFDs, nttyFDs,
|
||||
files, nfiles,
|
||||
handshakefds[1],
|
||||
logfd,
|
||||
&logfd,
|
||||
pidfile)))
|
||||
goto cleanup;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user