From 48027d7bc5ec0968ac4c4874bbea55701da25e2f Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Thu, 4 Aug 2022 11:45:19 +0200 Subject: [PATCH] Wayland screencast: fix crash on fd ownership violation We pass the fd we recieve from xdg-desktop-portal to PipeWire to connect to it and according to the specification PipeWire automatically closes it on disconnect or failure. We also close the fd ourself when we tear down the portal connection so we have to avoid doing this twice. Looks OBS studio just duplicates the fd passed to PipeWire so do the same in order to avoid the fd ownership violation once we stop sharing. The fd we recieve from xdg-desktop-portal is from PipeWire also using fcntl() with F_DUPFD_CLOEXEC option. Bug: chromium:1339236 Change-Id: Ia7aee36e520dd5ff9a40688a6807e31c4e636f8e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/270421 Commit-Queue: Alexander Cooper Reviewed-by: Alexander Cooper Cr-Commit-Position: refs/heads/main@{#37712} --- .../linux/wayland/shared_screencast_stream.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc index 3c4344fdba..5128091dc4 100644 --- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc @@ -10,6 +10,7 @@ #include "modules/desktop_capture/linux/wayland/shared_screencast_stream.h" +#include #include #include #include @@ -97,7 +98,6 @@ class SharedScreenCastStreamPrivate { private: uint32_t pw_stream_node_id_ = 0; - int pw_fd_ = -1; DesktopSize stream_size_ = {}; DesktopSize frame_size_; @@ -408,7 +408,6 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( egl_dmabuf_ = std::make_unique(); pw_stream_node_id_ = stream_node_id; - pw_fd_ = fd; pw_init(/*argc=*/nullptr, /*argc=*/nullptr); @@ -442,10 +441,11 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( { PipeWireThreadLoopLock thread_loop_lock(pw_main_loop_); - if (!pw_fd_) { - pw_core_ = pw_context_connect(pw_context_, nullptr, 0); + if (fd >= 0) { + pw_core_ = pw_context_connect_fd( + pw_context_, fcntl(fd, F_DUPFD_CLOEXEC), nullptr, 0); } else { - pw_core_ = pw_context_connect_fd(pw_context_, pw_fd_, nullptr, 0); + pw_core_ = pw_context_connect(pw_context_, nullptr, 0); } if (!pw_core_) { @@ -828,7 +828,7 @@ SharedScreenCastStream::CreateDefault() { } bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id) { - return private_->StartScreenCastStream(stream_node_id, 0); + return private_->StartScreenCastStream(stream_node_id, -1); } bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id,