From 516c3b7fe9284dc9701556aff2499ada185f45a4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 29 Jan 2012 12:58:59 +0100 Subject: [PATCH] QWaylandShmBuffer: use QTemporaryFile Instead of using mkstemp. Even current glibc versions do not open the file with O_CLOEXEC, so this code is not thread-safe. QTemporaryFile is. And since Qt 5.10, it will also use O_TMPFILE on Linux, so the file will not actually exists on disk. Take this opportunity to use the runtime directory instead of /tmp. There's no guarantee that the /tmp filesystem can support mmap'ing, while XDG_RUNTIME_DIR has that guarantee. It's also usually a tmpfs, so no data will be leaked to disk. Change-Id: I8d96dea9955d4c749b99fffd14cd5335d1114cef Reviewed-by: Giulio Camuffo --- .../wayland/qwaylandshmbackingstore.cpp | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index 045748a16c2..4c7c53b2f01 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -44,6 +44,8 @@ #include "qwaylandabstractdecoration_p.h" #include +#include +#include #include #include #include @@ -52,10 +54,7 @@ #include #include -#include -#include #include - QT_BEGIN_NAMESPACE namespace QtWaylandClient { @@ -72,28 +71,22 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, { int stride = size.width() * 4; int alloc = stride * size.height(); - char filename[] = "/tmp/wayland-shm-XXXXXX"; - int fd = mkstemp(filename); - if (fd < 0) { - qWarning("mkstemp %s failed: %s", filename, strerror(errno)); - return; - } - int flags = fcntl(fd, F_GETFD); - if (flags != -1) - fcntl(fd, F_SETFD, flags | FD_CLOEXEC); + int fd; - if (ftruncate(fd, alloc) < 0) { - qWarning("ftruncate failed: %s", strerror(errno)); - close(fd); + QTemporaryFile tmp(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + + QLatin1String("/wayland-shm-XXXXXX")); + if (!tmp.open() || !tmp.resize(alloc)) { + qWarning("QWaylandShmBuffer: failed: %s", qUtf8Printable(tmp.errorString())); return; } + fd = tmp.handle(); + + // map ourselves: QFile::map() will unmap when the object is destroyed, + // but we want this mapping to persist (unmapping in destructor) uchar *data = (uchar *) mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - unlink(filename); - if (data == (uchar *) MAP_FAILED) { - qWarning("mmap /dev/zero failed: %s", strerror(errno)); - close(fd); + qErrnoWarning("QWaylandShmBuffer: mmap failed"); return; } @@ -105,7 +98,6 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, mShmPool = wl_shm_create_pool(shm->object(), fd, alloc); init(wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(), stride, wl_format)); - close(fd); } QWaylandShmBuffer::~QWaylandShmBuffer(void)