kmsgrab: Only gain effective CAP_SYS_ADMIN when needed
This commit is contained in:
parent
302b61090b
commit
6309f478a2
6 changed files with 59 additions and 12 deletions
|
|
@ -113,8 +113,10 @@ else()
|
||||||
endif()
|
endif()
|
||||||
if(${SUNSHINE_ENABLE_DRM})
|
if(${SUNSHINE_ENABLE_DRM})
|
||||||
find_package(LIBDRM)
|
find_package(LIBDRM)
|
||||||
|
find_package(LIBCAP)
|
||||||
else()
|
else()
|
||||||
set(LIBDRM_FOUND OFF)
|
set(LIBDRM_FOUND OFF)
|
||||||
|
set(LIBCAP_FOUND OFF)
|
||||||
endif()
|
endif()
|
||||||
if(${SUNSHINE_ENABLE_WAYLAND})
|
if(${SUNSHINE_ENABLE_WAYLAND})
|
||||||
find_package(Wayland)
|
find_package(Wayland)
|
||||||
|
|
@ -129,10 +131,10 @@ else()
|
||||||
include_directories(${X11_INCLUDE_DIR})
|
include_directories(${X11_INCLUDE_DIR})
|
||||||
list(APPEND PLATFORM_TARGET_FILES sunshine/platform/linux/x11grab.cpp)
|
list(APPEND PLATFORM_TARGET_FILES sunshine/platform/linux/x11grab.cpp)
|
||||||
endif()
|
endif()
|
||||||
if(LIBDRM_FOUND)
|
if(LIBDRM_FOUND AND LIBCAP_FOUND)
|
||||||
add_compile_definitions(SUNSHINE_BUILD_DRM)
|
add_compile_definitions(SUNSHINE_BUILD_DRM)
|
||||||
include_directories(${LIBDRM_INCLUDE_DIRS})
|
include_directories(${LIBDRM_INCLUDE_DIRS} ${LIBCAP_INCLUDE_DIRS})
|
||||||
list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES})
|
list(APPEND PLATFORM_LIBRARIES ${LIBDRM_LIBRARIES} ${LIBCAP_LIBRARIES})
|
||||||
list(APPEND PLATFORM_TARGET_FILES sunshine/platform/linux/kmsgrab.cpp)
|
list(APPEND PLATFORM_TARGET_FILES sunshine/platform/linux/kmsgrab.cpp)
|
||||||
list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1)
|
list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ sudo apt install cmake gcc-10 g++-10 libssl-dev libavdevice-dev libboost-thread-
|
||||||
KMS allows Sunshine to grab the monitor with lower latency then through X11
|
KMS allows Sunshine to grab the monitor with lower latency then through X11
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt install cmake gcc-10 g++-10 libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libevdev-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libdrm-dev
|
sudo apt install cmake gcc-10 g++-10 libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libevdev-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libdrm-dev libcap-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compilation:
|
### Compilation:
|
||||||
|
|
@ -72,7 +72,7 @@ sunshine needs access to uinput to create mouse and gamepad events:
|
||||||
#### Additional Setup for KMS:
|
#### Additional Setup for KMS:
|
||||||
Please note that `cap_sys_admin` may as well be root, except you don't need to be root to run it.
|
Please note that `cap_sys_admin` may as well be root, except you don't need to be root to run it.
|
||||||
It's necessary to allow Sunshine to use KMS
|
It's necessary to allow Sunshine to use KMS
|
||||||
- `sudo setcap cap_sys_admin+ep sunshine`
|
- `sudo setcap cap_sys_admin+p sunshine`
|
||||||
|
|
||||||
### Trouleshooting:
|
### Trouleshooting:
|
||||||
- If you get "Could not create Sunshine Gamepad: Permission Denied", ensure you are part of the group "input":
|
- If you get "Could not create Sunshine Gamepad: Permission Denied", ensure you are part of the group "input":
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ environment:
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- sh: sudo apt update --ignore-missing
|
- sh: sudo apt update --ignore-missing
|
||||||
- sh: sudo apt install -y build-essential fakeroot gcc-10 g++-10 cmake libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libevdev-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libdrm-dev
|
- sh: sudo apt install -y build-essential fakeroot gcc-10 g++-10 cmake libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libevdev-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libdrm-dev libcap-dev
|
||||||
- cmd: C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-opus mingw-w64-x86_64-x265 mingw-w64-x86_64-boost git yasm nasm diffutils make"
|
- cmd: C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-opus mingw-w64-x86_64-x265 mingw-w64-x86_64-boost git yasm nasm diffutils make"
|
||||||
|
|
||||||
before_build:
|
before_build:
|
||||||
|
|
|
||||||
21
cmake/FindLIBCAP.cmake
Normal file
21
cmake/FindLIBCAP.cmake
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# - Try to find Libcap
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# LIBCAP_FOUND - system has Libcap
|
||||||
|
# LIBCAP_INCLUDE_DIRS - the Libcap include directory
|
||||||
|
# LIBCAP_LIBRARIES - the libraries needed to use Libcap
|
||||||
|
# LIBCAP_DEFINITIONS - Compiler switches required for using Libcap
|
||||||
|
|
||||||
|
# Use pkg-config to get the directories and then use these values
|
||||||
|
# in the find_path() and find_library() calls
|
||||||
|
find_package(PkgConfig)
|
||||||
|
pkg_check_modules(PC_LIBCAP libcap)
|
||||||
|
|
||||||
|
set(LIBCAP_DEFINITIONS ${PC_LIBCAP_CFLAGS})
|
||||||
|
|
||||||
|
find_path(LIBCAP_INCLUDE_DIRS sys/capability.h PATHS ${PC_LIBCAP_INCLUDEDIR} ${PC_LIBCAP_INCLUDE_DIRS})
|
||||||
|
find_library(LIBCAP_LIBRARIES NAMES libcap.so PATHS ${PC_LIBCAP_LIBDIR} ${PC_LIBCAP_LIBRARY_DIRS})
|
||||||
|
mark_as_advanced(LIBCAP_INCLUDE_DIRS LIBCAP_LIBRARIES)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(LIBCAP REQUIRED_VARS LIBCAP_LIBRARIES LIBCAP_INCLUDE_DIRS)
|
||||||
|
|
@ -38,7 +38,7 @@ Architecture: amd64
|
||||||
Maintainer: @loki
|
Maintainer: @loki
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Version: 0.10.2
|
Version: 0.10.2
|
||||||
Depends: libssl1.1, libavdevice58, libboost-thread1.67.0 | libboost-thread1.71.0, libboost-filesystem1.67.0 | libboost-filesystem1.71.0, libboost-log1.67.0 | libboost-log1.71.0, libpulse0, libopus0, libxcb-shm0, libxcb-xfixes0, libxtst6, libevdev2, libdrm2
|
Depends: libssl1.1, libavdevice58, libboost-thread1.67.0 | libboost-thread1.71.0, libboost-filesystem1.67.0 | libboost-filesystem1.71.0, libboost-log1.67.0 | libboost-log1.71.0, libpulse0, libopus0, libxcb-shm0, libxcb-xfixes0, libxtst6, libevdev2, libdrm2, libcap
|
||||||
Description: Gamestream host for Moonlight
|
Description: Gamestream host for Moonlight
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
@ -92,8 +92,8 @@ fi
|
||||||
# Ensure Sunshine can grab images from KMS
|
# Ensure Sunshine can grab images from KMS
|
||||||
path_to_setcap=$(which setcap)
|
path_to_setcap=$(which setcap)
|
||||||
if [ -x "$path_to_setcap" ] ; then
|
if [ -x "$path_to_setcap" ] ; then
|
||||||
echo "$path_to_setcap cap_sys_admin+ep /usr/bin/sunshine"
|
echo "$path_to_setcap cap_sys_admin+p /usr/bin/sunshine"
|
||||||
$path_to_setcap cap_sys_admin+ep /usr/bin/sunshine
|
$path_to_setcap cap_sys_admin+p /usr/bin/sunshine
|
||||||
fi
|
fi
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
#include <sys/capability.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
|
@ -25,6 +26,27 @@ namespace platf {
|
||||||
|
|
||||||
namespace kms {
|
namespace kms {
|
||||||
|
|
||||||
|
class cap_sys_admin {
|
||||||
|
public:
|
||||||
|
cap_sys_admin() {
|
||||||
|
caps = cap_get_proc();
|
||||||
|
cap_value_t sys_admin = CAP_SYS_ADMIN;
|
||||||
|
if(cap_set_flag(caps, CAP_EFFECTIVE, 1, &sys_admin, CAP_SET) || cap_set_proc(caps)) {
|
||||||
|
BOOST_LOG(error) << "Failed to gain CAP_SYS_ADMIN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~cap_sys_admin() {
|
||||||
|
cap_value_t sys_admin = CAP_SYS_ADMIN;
|
||||||
|
if(cap_set_flag(caps, CAP_EFFECTIVE, 1, &sys_admin, CAP_CLEAR) || cap_set_proc(caps)) {
|
||||||
|
BOOST_LOG(error) << "Failed to drop CAP_SYS_ADMIN";
|
||||||
|
}
|
||||||
|
cap_free(caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
cap_t caps;
|
||||||
|
};
|
||||||
|
|
||||||
class wrapper_fb {
|
class wrapper_fb {
|
||||||
public:
|
public:
|
||||||
wrapper_fb(drmModeFB *fb)
|
wrapper_fb(drmModeFB *fb)
|
||||||
|
|
@ -200,6 +222,7 @@ public:
|
||||||
using connector_interal_t = util::safe_ptr<drmModeConnector, drmModeFreeConnector>;
|
using connector_interal_t = util::safe_ptr<drmModeConnector, drmModeFreeConnector>;
|
||||||
|
|
||||||
int init(const char *path) {
|
int init(const char *path) {
|
||||||
|
cap_sys_admin admin;
|
||||||
fd.el = open(path, O_RDWR);
|
fd.el = open(path, O_RDWR);
|
||||||
|
|
||||||
if(fd.el < 0) {
|
if(fd.el < 0) {
|
||||||
|
|
@ -226,6 +249,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_t fb(plane_t::pointer plane) {
|
fb_t fb(plane_t::pointer plane) {
|
||||||
|
cap_sys_admin admin;
|
||||||
auto fb = drmModeGetFB2(fd.el, plane->fb_id);
|
auto fb = drmModeGetFB2(fd.el, plane->fb_id);
|
||||||
if(fb) {
|
if(fb) {
|
||||||
return std::make_unique<wrapper_fb>(fb);
|
return std::make_unique<wrapper_fb>(fb);
|
||||||
|
|
@ -451,7 +475,7 @@ public:
|
||||||
|
|
||||||
if(!fb->handles[0]) {
|
if(!fb->handles[0]) {
|
||||||
BOOST_LOG(error)
|
BOOST_LOG(error)
|
||||||
<< "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+ep sunshine]"sv;
|
<< "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+p sunshine]"sv;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -545,7 +569,7 @@ public:
|
||||||
|
|
||||||
if(!fb->handles[0]) {
|
if(!fb->handles[0]) {
|
||||||
BOOST_LOG(error)
|
BOOST_LOG(error)
|
||||||
<< "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+ep sunshine]"sv;
|
<< "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+p sunshine]"sv;
|
||||||
return capture_e::error;
|
return capture_e::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -967,7 +991,7 @@ std::vector<std::string> kms_display_names() {
|
||||||
|
|
||||||
if(!fb->handles[0]) {
|
if(!fb->handles[0]) {
|
||||||
BOOST_LOG(error)
|
BOOST_LOG(error)
|
||||||
<< "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+ep sunshine]"sv;
|
<< "Couldn't get handle for DRM Framebuffer ["sv << plane->fb_id << "]: Possibly not permitted: do [sudo setcap cap_sys_admin+p sunshine]"sv;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue