[Spice-devel] [PATCH spice-xpi 1/4] Avoid a race leading to a plugin crash

Alon Levy alevy at redhat.com
Fri Feb 24 03:04:22 PST 2012


On Fri, Feb 24, 2012 at 11:54:35AM +0100, Marc-André Lureau wrote:
> When the child exits quickly (failed to start etc..), it doesn't get
> tracked properly and when receiving sigchld, "fake_this" may be NULL
> leading to a crash (fake_this = s_children[info->si_pid])
> ---
>  SpiceXPI/src/plugin/plugin.cpp |   34 +++++++++++++++++++++++++++++++---
>  1 files changed, 31 insertions(+), 3 deletions(-)
> 

ACK. Just minor nitpick and silly question.

> diff --git a/SpiceXPI/src/plugin/plugin.cpp b/SpiceXPI/src/plugin/plugin.cpp
> index b82d074..c3d2d91 100644
> --- a/SpiceXPI/src/plugin/plugin.cpp
> +++ b/SpiceXPI/src/plugin/plugin.cpp
> @@ -569,10 +569,27 @@ void nsPluginInstance::Connect()
>          return;
>      }
>  
> +    /* use a pipe for the children to wait until it gets tracked */
> +    int pipe_fds[2] = { -1, -1 };
empty line here

> +    if (pipe(pipe_fds) < 0) {
> +        perror("spice-xpi system error");
> +        return;
> +    }
> +
>      pid_t child = fork();
>      LOG_DEBUG("child pid: " << child);
>      if (child == 0)
>      {
> +        close (pipe_fds[1]);
> +        pipe_fds[1] = -1;
> +
> +        char c;
> +        if (read(pipe_fds[0], &c, 1) != 0)
> +            LOG_ERROR("Invalid read on pipe");
> +
> +        close (pipe_fds[0]);
> +        pipe_fds[0] = -1;
> +
>          execl("/usr/libexec/spice-xpi-client", "/usr/libexec/spice-xpi-client", NULL);
>          LOG_ERROR("ERROR failed to run spice-xpi-client");
>  
> @@ -584,6 +601,14 @@ void nsPluginInstance::Connect()
>      }
>      else
>      {
> +        close(pipe_fds[0]);
> +        pipe_fds[0] = -1;
> +
> +        s_children[child] = this;
> +
> +        close(pipe_fds[1]);
> +        pipe_fds[1] = -1;
> +

So you're not doing a write, but instead just a close, and so the
child's read should return 0?

>          m_external_controller.SetFilename(socket_file);
>  
>          if (m_external_controller.Connect(10) != 0)
> @@ -659,8 +684,6 @@ void nsPluginInstance::Connect()
>  
>          // set connected status
>          m_connected_status = -1;
> -
> -        s_children[child] = this;
>      }
>  }
>  
> @@ -765,6 +788,11 @@ void nsPluginInstance::SigchldRoutine(int sig, siginfo_t *info, void *uap)
>  
>      if (!getenv("SPICE_XPI_DEBUG")) {
>          nsPluginInstance *fake_this = s_children[info->si_pid];
> +        if (fake_this == NULL) {
> +            LOG_ERROR("Invalid children signal");
> +            return;
> +        }
> +
>          fake_this->CallOnDisconnected(exit_code);
>          fake_this->m_external_controller.Disconnect();
>      }
> @@ -777,7 +805,7 @@ void nsPluginInstance::SigchldRoutine(int sig, siginfo_t *info, void *uap)
>  // ==============================
>  //
>  // here the plugin is asked by Mozilla to tell if it is scriptable
> -// we should return a valid interface id and a pointer to 
> +// we should return a valid interface id and a pointer to
>  // nsScriptablePeer interface which we should have implemented
>  // and which should be defined in the corressponding *.xpt file
>  // in the bin/components folder
> -- 
> 1.7.7.6
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list