From: Emil Velikov Date: Thu, 30 Aug 2018 16:24:16 +0000 (+0100) Subject: pipe-loader: add a dup() in pipe_loader_sw_probe_kms X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7419b224139b47ea98d1bc4c5dab7370076b214f;p=mesa.git pipe-loader: add a dup() in pipe_loader_sw_probe_kms 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 --- diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader.h b/src/gallium/auxiliary/pipe-loader/pipe_loader.h index be7e25afb02..05be94cae31 100644 --- a/src/gallium/auxiliary/pipe-loader/pipe_loader.h +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader.h @@ -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 diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c index 84894c0caf6..d387ce90d32 100644 --- a/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c @@ -25,6 +25,10 @@ * **************************************************************************/ +#ifdef HAVE_PIPE_LOADER_KMS +#include +#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; }