forked from pool/kinit
202 lines
7.8 KiB
Diff
202 lines
7.8 KiB
Diff
|
From ff991d84b66b7aa68c6f24f3ec4b0e35b830a789 Mon Sep 17 00:00:00 2001
|
||
|
From: Hrvoje Senjan <hrvoje.senjan@gmail.com>
|
||
|
Date: Fri, 11 Apr 2014 17:41:46 +0200
|
||
|
Subject: [PATCH 1/1] Use capabilities instead of SUID where available
|
||
|
|
||
|
This requires that both libcap libraries and setcap
|
||
|
executable are found during build, otherwise the old
|
||
|
procedure of SUID is used
|
||
|
|
||
|
CCMAIL: krahmer@suse.com
|
||
|
CCMAIL: kde-packager@kde.org
|
||
|
|
||
|
REVIEW: 117125
|
||
|
(cherry picked from commit e898d13b430692e775060d49342181192e122fdf)
|
||
|
---
|
||
|
CMakeLists.txt | 11 +++++++-
|
||
|
cmake/FindLibcap.cmake | 59 +++++++++++++++++++++++++++++++++++++++
|
||
|
src/config-kdeinit.h.cmake | 1 +
|
||
|
src/start_kdeinit/CMakeLists.txt | 20 +++++++++----
|
||
|
src/start_kdeinit/start_kdeinit.c | 14 ++++++++++
|
||
|
5 files changed, 99 insertions(+), 6 deletions(-)
|
||
|
create mode 100644 cmake/FindLibcap.cmake
|
||
|
|
||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||
|
index 8bd43d8..2ba9bbd 100644
|
||
|
--- a/CMakeLists.txt
|
||
|
+++ b/CMakeLists.txt
|
||
|
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12)
|
||
|
project(KInit)
|
||
|
|
||
|
find_package(ECM 0.0.12 REQUIRED NO_MODULE)
|
||
|
-set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
|
||
|
+set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||
|
|
||
|
set(REQUIRED_QT_VERSION "5.2")
|
||
|
find_package(Qt5 "${REQUIRED_QT_VERSION}" CONFIG REQUIRED Core Gui DBus)
|
||
|
@@ -50,6 +50,15 @@ if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
|
||
|
# Remove when we depend on CMake 3.0.0
|
||
|
endif()
|
||
|
|
||
|
+if (NOT WIN32)
|
||
|
+find_package(Libcap)
|
||
|
+set_package_properties(Libcap PROPERTIES
|
||
|
+ TYPE OPTIONAL
|
||
|
+ PURPOSE "KInit needs setcap in order to install start_kdeinit with CAP_SYS_RESOURCE capabilities"
|
||
|
+ )
|
||
|
+endif ()
|
||
|
+set(HAVE_CAPABILITIES ${Libcap_FOUND})
|
||
|
+
|
||
|
set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5Init")
|
||
|
ecm_configure_package_config_file(
|
||
|
"${CMAKE_CURRENT_SOURCE_DIR}/KF5InitConfig.cmake.in"
|
||
|
diff --git a/cmake/FindLibcap.cmake b/cmake/FindLibcap.cmake
|
||
|
new file mode 100644
|
||
|
index 0000000..4a32446
|
||
|
--- /dev/null
|
||
|
+++ b/cmake/FindLibcap.cmake
|
||
|
@@ -0,0 +1,59 @@
|
||
|
+# Try to find the setcap binary and cap libraries
|
||
|
+#
|
||
|
+# This will define:
|
||
|
+#
|
||
|
+# Libcap_FOUND - system has the cap library and setcap binary
|
||
|
+# Libcap_LIBRARIES - cap libraries to link against
|
||
|
+# SETCAP_EXECUTABLE - path of the setcap binary
|
||
|
+# In addition, the following targets are defined:
|
||
|
+#
|
||
|
+# Libcap::SetCapabilities
|
||
|
+#
|
||
|
+
|
||
|
+
|
||
|
+# Copyright (c) 2014, Hrvoje Senjan, <hrvoje.senjan@gmail.com>
|
||
|
+#
|
||
|
+# Redistribution and use in source and binary forms, with or without
|
||
|
+# modification, are permitted provided that the following conditions
|
||
|
+# are met:
|
||
|
+#
|
||
|
+# 1. Redistributions of source code must retain the copyright
|
||
|
+# notice, this list of conditions and the following disclaimer.
|
||
|
+# 2. Redistributions in binary form must reproduce the copyright
|
||
|
+# notice, this list of conditions and the following disclaimer in the
|
||
|
+# documentation and/or other materials provided with the distribution.
|
||
|
+# 3. The name of the author may not be used to endorse or promote products
|
||
|
+# derived from this software without specific prior written permission.
|
||
|
+#
|
||
|
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||
|
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||
|
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||
|
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
|
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||
|
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||
|
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
+
|
||
|
+find_program(SETCAP_EXECUTABLE NAMES setcap DOC "The setcap executable")
|
||
|
+
|
||
|
+find_library(Libcap_LIBRARIES NAMES cap DOC "The cap (capabilities) library")
|
||
|
+
|
||
|
+include(FindPackageHandleStandardArgs)
|
||
|
+find_package_handle_standard_args(Libcap FOUND_VAR Libcap_FOUND
|
||
|
+ REQUIRED_VARS SETCAP_EXECUTABLE Libcap_LIBRARIES)
|
||
|
+
|
||
|
+if(Libcap_FOUND AND NOT TARGET Libcap::SetCapabilities)
|
||
|
+ add_executable(Libcap::SetCapabilities IMPORTED)
|
||
|
+ set_target_properties(Libcap::SetCapabilities PROPERTIES
|
||
|
+ IMPORTED_LOCATION "${SETCAP_EXECUTABLE}"
|
||
|
+ )
|
||
|
+endif()
|
||
|
+
|
||
|
+mark_as_advanced(SETCAP_EXECUTABLE Libcap_LIBRARIES)
|
||
|
+
|
||
|
+include(FeatureSummary)
|
||
|
+set_package_properties(Libcap PROPERTIES
|
||
|
+ URL https://sites.google.com/site/fullycapable/
|
||
|
+ DESCRIPTION "Capabilities are a measure to limit the omnipotence of the superuser.")
|
||
|
diff --git a/src/config-kdeinit.h.cmake b/src/config-kdeinit.h.cmake
|
||
|
index c89c713..8f162fa 100644
|
||
|
--- a/src/config-kdeinit.h.cmake
|
||
|
+++ b/src/config-kdeinit.h.cmake
|
||
|
@@ -13,6 +13,7 @@
|
||
|
#cmakedefine01 CAN_CLOBBER_ARGV
|
||
|
|
||
|
#cmakedefine01 HAVE_X11
|
||
|
+#cmakedefine01 HAVE_CAPABILITIES
|
||
|
#cmakedefine01 HAVE_SYS_SELECT_H
|
||
|
|
||
|
/* for start_kdeinit */
|
||
|
diff --git a/src/start_kdeinit/CMakeLists.txt b/src/start_kdeinit/CMakeLists.txt
|
||
|
index 6bfc496..8f52ea9 100644
|
||
|
--- a/src/start_kdeinit/CMakeLists.txt
|
||
|
+++ b/src/start_kdeinit/CMakeLists.txt
|
||
|
@@ -5,10 +5,20 @@ install(TARGETS start_kdeinit DESTINATION ${LIBEXEC_INSTALL_DIR})
|
||
|
install(TARGETS start_kdeinit_wrapper DESTINATION ${LIBEXEC_INSTALL_DIR})
|
||
|
|
||
|
if (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||
|
- MESSAGE(STATUS "Using setuid root kdeinit wrapper in order to protect it from bad Linux OOM-killer")
|
||
|
- set(KDEINIT_OOM_PROTECT 1)
|
||
|
- install(CODE "
|
||
|
- set(START_KDEINIT_PATH \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LIBEXEC_INSTALL_DIR}/start_kdeinit\")
|
||
|
- EXECUTE_PROCESS(COMMAND sh -c \"chown 0 '\${START_KDEINIT_PATH}' && chmod u+s '\${START_KDEINIT_PATH}'\")
|
||
|
+ set(KDEINIT_OOM_PROTECT 1)
|
||
|
+ if (Libcap_FOUND)
|
||
|
+ message(STATUS "Using capabilities kdeinit wrapper in order to protect it from bad Linux OOM-killer")
|
||
|
+ install( CODE "execute_process(
|
||
|
+ COMMAND
|
||
|
+ ${SETCAP_EXECUTABLE}
|
||
|
+ CAP_SYS_RESOURCE=+ep
|
||
|
+ $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LIBEXEC_INSTALL_DIR}/start_kdeinit)"
|
||
|
+ )
|
||
|
+ else()
|
||
|
+ message(STATUS "Using setuid root kdeinit wrapper in order to protect it from bad Linux OOM-killer")
|
||
|
+ install(CODE "
|
||
|
+ set(START_KDEINIT_PATH \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LIBEXEC_INSTALL_DIR}/start_kdeinit\")
|
||
|
+ EXECUTE_PROCESS(COMMAND sh -c \"chown 0 '\${START_KDEINIT_PATH}' && chmod u+s '\${START_KDEINIT_PATH}'\")
|
||
|
")
|
||
|
+ endif ()
|
||
|
endif ()
|
||
|
diff --git a/src/start_kdeinit/start_kdeinit.c b/src/start_kdeinit/start_kdeinit.c
|
||
|
index 3c733e7..07a28d3 100644
|
||
|
--- a/src/start_kdeinit/start_kdeinit.c
|
||
|
+++ b/src/start_kdeinit/start_kdeinit.c
|
||
|
@@ -27,6 +27,9 @@
|
||
|
#include <string.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <unistd.h>
|
||
|
+#if HAVE_CAPABILITIES
|
||
|
+#include <sys/capability.h>
|
||
|
+#endif
|
||
|
|
||
|
#define EXECUTE CMAKE_INSTALL_PREFIX"/"BIN_INSTALL_DIR "/kdeinit5"
|
||
|
|
||
|
@@ -98,6 +101,9 @@ int main(int argc, char **argv)
|
||
|
unsigned i;
|
||
|
char **orig_environ = NULL;
|
||
|
char header[ 7 ];
|
||
|
+#if HAVE_CAPABILITIES
|
||
|
+ cap_t caps;
|
||
|
+#endif
|
||
|
if (pipe(pipes) < 0) {
|
||
|
perror("pipe()");
|
||
|
return 1;
|
||
|
@@ -111,6 +117,14 @@ int main(int argc, char **argv)
|
||
|
perror("fork()");
|
||
|
return 1;
|
||
|
default: /* parent, drop privileges and exec */
|
||
|
+#if HAVE_CAPABILITIES
|
||
|
+ caps = cap_init();
|
||
|
+ if (cap_set_proc(caps) < 0) {
|
||
|
+ perror("cap_set_proc()");
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ cap_free(caps);
|
||
|
+#endif
|
||
|
if (setgid(getgid())) {
|
||
|
perror("setgid()");
|
||
|
return 1;
|
||
|
--
|
||
|
1.9.1
|
||
|
|