@@ -1076,6 +1076,19 @@ namespace platf {
10761076 }
10771077
10781078 std::shared_ptr<display_t > display (mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
1079+ // Keep KMS as first element to check before dropping CAP_SYS_ADMIN
1080+ #ifdef SUNSHINE_BUILD_DRM
1081+ if (sources[source::KMS ]) {
1082+ BOOST_LOG (info) << " Screencasting with KMS" sv;
1083+ return kms_display (hwdevice_type, display_name, config);
1084+ }
1085+ #endif
1086+
1087+ // KMS capture was passed; drop CAP_SYS_ADMIN only.
1088+ if (has_elevated_privileges (false )) {
1089+ drop_elevated_privileges (false );
1090+ }
1091+
10791092#ifdef SUNSHINE_BUILD_CUDA
10801093 if (sources[source::NVFBC ] && hwdevice_type == mem_type_e::cuda) {
10811094 BOOST_LOG (info) << " Screencasting with NvFBC" sv;
@@ -1088,12 +1101,6 @@ namespace platf {
10881101 return wl_display (hwdevice_type, display_name, config);
10891102 }
10901103#endif
1091- #ifdef SUNSHINE_BUILD_DRM
1092- if (sources[source::KMS ]) {
1093- BOOST_LOG (info) << " Screencasting with KMS" sv;
1094- return kms_display (hwdevice_type, display_name, config);
1095- }
1096- #endif
10971104#ifdef SUNSHINE_BUILD_X11
10981105 if (sources[source::X11 ]) {
10991106 BOOST_LOG (info) << " Screencasting with X11" sv;
@@ -1261,26 +1268,30 @@ namespace platf {
12611268 }
12621269
12631270#if !defined(__FreeBSD__)
1264- constexpr std::array<cap_value_t , 2 > ELEVATED_PRIVILEGES_EFFECTIVE {CAP_SYS_ADMIN , CAP_SYS_NICE };
1265- constexpr std::array<cap_value_t , 2 > ELEVATED_PRIVILEGES_PERMITTED {CAP_SYS_ADMIN , CAP_SYS_NICE };
1271+ static constexpr cap_value_t FULL_CAPS [] = {CAP_SYS_ADMIN , CAP_SYS_NICE };
1272+ static constexpr cap_value_t ADMIN_CAPS [] = {CAP_SYS_ADMIN };
1273+
1274+ constexpr std::span<const cap_value_t > ELEVATED_PRIVILEGES_FULL {FULL_CAPS };
1275+ constexpr std::span<const cap_value_t > ELEVATED_PRIVILEGES_ADMIN {ADMIN_CAPS };
12661276#endif
12671277
1268- bool has_elevated_privileges () {
1278+ bool has_elevated_privileges (bool all_caps ) {
12691279#if !defined(__FreeBSD__)
1280+ const auto caps_to_check = all_caps ? ELEVATED_PRIVILEGES_FULL : ELEVATED_PRIVILEGES_ADMIN ;
12701281 const cap_t caps = cap_get_proc ();
12711282 if (!caps) {
12721283 BOOST_LOG (error) << " [misc] has_elevated_privileges failed to get process capabilities." sv;
12731284 return false ;
12741285 }
1275- for (const auto c : ELEVATED_PRIVILEGES_EFFECTIVE ) {
1286+ for (const auto c : caps_to_check ) {
12761287 cap_flag_value_t cap_flags_value;
12771288 cap_get_flag (caps, c, CAP_EFFECTIVE , &cap_flags_value);
12781289 if (cap_flags_value == CAP_SET ) {
12791290 BOOST_LOG (debug) << " [misc] has_elevated_privileges found effective cap:" sv << c;
12801291 return true ;
12811292 }
12821293 }
1283- for (const auto c : ELEVATED_PRIVILEGES_PERMITTED ) {
1294+ for (const auto c : caps_to_check ) {
12841295 cap_flag_value_t cap_flags_value;
12851296 cap_get_flag (caps, c, CAP_PERMITTED , &cap_flags_value);
12861297 if (cap_flags_value == CAP_SET ) {
@@ -1293,17 +1304,18 @@ namespace platf {
12931304 return false ;
12941305 }
12951306
1296- void drop_elevated_privileges () {
1307+ void drop_elevated_privileges (bool all_caps ) {
12971308#if !defined(__FreeBSD__)
12981309 bool failed = false ;
1310+ const auto caps_to_drop = all_caps ? ELEVATED_PRIVILEGES_FULL : ELEVATED_PRIVILEGES_ADMIN ;
12991311 const cap_t caps = cap_get_proc ();
13001312 if (!caps) {
13011313 BOOST_LOG (error) << " [misc] drop_elevated_privileges failed to get process capabilities" sv;
13021314 return ;
13031315 }
13041316
1305- cap_set_flag (caps, CAP_EFFECTIVE , ELEVATED_PRIVILEGES_EFFECTIVE .size (), ELEVATED_PRIVILEGES_EFFECTIVE .data (), CAP_CLEAR );
1306- cap_set_flag (caps, CAP_PERMITTED , ELEVATED_PRIVILEGES_PERMITTED .size (), ELEVATED_PRIVILEGES_PERMITTED .data (), CAP_CLEAR );
1317+ cap_set_flag (caps, CAP_EFFECTIVE , caps_to_drop .size (), caps_to_drop .data (), CAP_CLEAR );
1318+ cap_set_flag (caps, CAP_PERMITTED , caps_to_drop .size (), caps_to_drop .data (), CAP_CLEAR );
13071319
13081320 if (cap_set_proc (caps) != 0 ) {
13091321 BOOST_LOG (error) << " [misc] drop_elevated_privileges failed to prune capabilities: " sv << std::strerror (errno);
0 commit comments