pipe-loader: add a dup() in pipe_loader_sw_probe_kms
authorEmil Velikov <emil.velikov@collabora.com>
Thu, 30 Aug 2018 16:24:16 +0000 (17:24 +0100)
committerEmil Velikov <emil.l.velikov@gmail.com>
Wed, 3 Oct 2018 12:38:05 +0000 (13:38 +0100)
The pipe_loader_release API closes the fd given, even if the pipe-loader
should _not_ take ownership of it.

With earlier commit we fixed pipe_loader_drm_probe_fd, and now with
cover the final piece.

Note that unlike the DRM case, here the caller _did_ forget to dup
before using it ... most likely leading to all sorts of fun.

Don't forget the close in the error path. Seems like the things are a
bit leaky/asymmetrical with the semi-recent config work. But we can shave
that yak another day ;-)

Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
src/gallium/auxiliary/pipe-loader/pipe_loader.h
src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c

index be7e25afb0276c3704868b2757c5459ebc0db7e4..05be94cae31b106ba0fce86254ec457f26a43787 100644 (file)
@@ -135,6 +135,9 @@ pipe_loader_release(struct pipe_loader_device **devs, int ndev);
  *
  * This function is platform-specific.
  *
+ * Function does not take ownership of the fd, but duplicates it locally.
+ * The local fd is closed during pipe_loader_release.
+ *
  * \sa pipe_loader_probe
  */
 bool
index 84894c0caf6993cf16243ba1aac9c527cc3d4f3f..d387ce90d32c13aa1a71791690483b79ce129ce2 100644 (file)
  *
  **************************************************************************/
 
+#ifdef HAVE_PIPE_LOADER_KMS
+#include <fcntl.h>
+#endif
+
 #include "pipe_loader_priv.h"
 
 #include "util/u_memory.h"
@@ -171,11 +175,12 @@ pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd)
    if (!pipe_loader_sw_probe_init_common(sdev))
       goto fail;
 
-   sdev->fd = fd;
+   if (fd < 0 || (sdev->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0)
+      goto fail;
 
    for (i = 0; sdev->dd->winsys[i].name; i++) {
       if (strcmp(sdev->dd->winsys[i].name, "kms_dri") == 0) {
-         sdev->ws = sdev->dd->winsys[i].create_winsys(fd);
+         sdev->ws = sdev->dd->winsys[i].create_winsys(sdev->fd);
          break;
       }
    }
@@ -187,6 +192,8 @@ pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd)
 
 fail:
    pipe_loader_sw_probe_teardown_common(sdev);
+   if (sdev->fd != -1)
+      close(sdev->fd);
    FREE(sdev);
    return false;
 }