kinit/0001-Use-capabilities-instead-of-SUID-where-available.patch

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