From a2031d3a3a6ff26640f5c8cc0d76a0076c6e74cc Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Wed, 6 Dec 2017 20:35:21 +0100 Subject: CPack/RPM: check executable flags for debuginfo packages Debuginfo packages can not be created from programs and shared libraries that do not have execute permissions. --- .../dev/cpack-rpm-check-executable-flags.rst | 6 ++ Modules/CPackRPM.cmake | 75 +++++++++++++++++++++- .../CPack/tests/DEBUGINFO/ExpectedFiles.cmake | 4 +- Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake | 4 ++ .../tests/EXTRA_SLASH_IN_PATH/ExpectedFiles.cmake | 4 +- .../CPack/tests/EXTRA_SLASH_IN_PATH/test.cmake | 4 ++ .../tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake | 6 +- 7 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 Help/release/dev/cpack-rpm-check-executable-flags.rst diff --git a/Help/release/dev/cpack-rpm-check-executable-flags.rst b/Help/release/dev/cpack-rpm-check-executable-flags.rst new file mode 100644 index 0000000..30475d6 --- /dev/null +++ b/Help/release/dev/cpack-rpm-check-executable-flags.rst @@ -0,0 +1,6 @@ +cpack-rpm-check-executable-flags +-------------------------------- + +* The :module:`CPackRPM` module learned to enable enforcing of execute + privilages on programs and shared libraries. + See :variable:`CPACK_RPM_INSTALL_WITH_EXEC` variable. diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index c5a27f9..faa2df8 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -691,6 +691,22 @@ # are the same as for :variable:`CPACK_RPM_DEFAULT_FILE_PERMISSIONS`. # Note that must be in upper-case. # +# .. variable:: CPACK_RPM_INSTALL_WITH_EXEC +# +# force execute permissions on programs and shared libraries +# +# * Mandatory : NO +# * Default : - (system default) +# +# Force set owner, group and world execute permissions on programs and shared +# libraries. This can be used for creating valid rpm packages on systems such +# as Debian where shared libraries do not have execute permissions set. +# +# .. note:: +# +# Programs and shared libraries without execute permissions are ignored during +# separation of debug symbols from the binary for debuginfo packages. +# # Packaging of Symbolic Links # ^^^^^^^^^^^^^^^^^^^^^^^^^^^ # @@ -751,7 +767,8 @@ # .. note:: # # Packages generated from packages without binary files, with binary files but -# without execute permissions or without debug symbols will be empty. +# without execute permissions or without debug symbols will cause packaging +# termination. # # .. variable:: CPACK_BUILD_SOURCE_DIRS # @@ -939,6 +956,35 @@ # Author: Eric Noulard with the help of Alexander Neundorf. +function(get_file_permissions FILE RETURN_VAR) + execute_process(COMMAND ls -l ${FILE} + OUTPUT_VARIABLE permissions_ + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + cmake_policy(SET CMP0007 NEW) + string(REPLACE " " ";" permissions_ "${permissions_}") + list(GET permissions_ 0 permissions_) + + unset(text_notation_) + set(any_chars_ ".") + foreach(PERMISSION_TYPE "OWNER" "GROUP" "WORLD") + if(permissions_ MATCHES "${any_chars_}r.*") + list(APPEND text_notation_ "${PERMISSION_TYPE}_READ") + endif() + string(APPEND any_chars_ ".") + if(permissions_ MATCHES "${any_chars_}w.*") + list(APPEND text_notation_ "${PERMISSION_TYPE}_WRITE") + endif() + string(APPEND any_chars_ ".") + if(permissions_ MATCHES "${any_chars_}x.*") + list(APPEND text_notation_ "${PERMISSION_TYPE}_EXECUTE") + endif() + endforeach() + + set(${RETURN_VAR} "${text_notation_}" PARENT_SCOPE) +endfunction() + function(get_unix_permissions_octal_notation PERMISSIONS_VAR RETURN_VAR) set(PERMISSIONS ${${PERMISSIONS_VAR}}) list(LENGTH PERMISSIONS PERM_LEN_PRE) @@ -1515,7 +1561,7 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR) RESULT_VARIABLE OBJDUMP_EXEC_RESULT OUTPUT_VARIABLE OBJDUMP_OUT ERROR_QUIET) - # Check that if the given file was executable or not + # Check if the given file is an executable or not if(NOT OBJDUMP_EXEC_RESULT) string(FIND "${OBJDUMP_OUT}" "debug" FIND_RESULT) if(FIND_RESULT GREATER -1) @@ -1560,6 +1606,31 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR) else() message(WARNING "CPackRPM: File: ${F} does not contain debug symbols. They will possibly be missing from debuginfo package!") endif() + + get_file_permissions("${WORKING_DIR}/${F}" permissions_) + cmake_policy(SET CMP0057 NEW) + if(NOT "USER_EXECUTE" IN_LIST permissions_ AND + NOT "GROUP_EXECUTE" IN_LIST permissions_ AND + NOT "WORLD_EXECUTE" IN_LIST permissions_) + if(CPACK_RPM_INSTALL_WITH_EXEC) + execute_process(COMMAND chmod a+x ${WORKING_DIR}/${F} + RESULT_VARIABLE res_ + ERROR_VARIABLE err_ + OUTPUT_QUIET) + + if(res_) + message(FATAL_ERROR "CPackRPM: could not apply execute permissions " + "requested by CPACK_RPM_INSTALL_WITH_EXEC variable on " + "'${WORKING_DIR}/${F}'! Reason: '${err_}'") + endif() + else() + message(AUTHOR_WARNING "CPackRPM: File: ${WORKING_DIR}/${F} does not " + "have execute permissions. Debuginfo symbols will not be extracted" + "! Missing debuginfo may cause packaging failure. Consider setting " + "execute permissions or setting 'CPACK_RPM_INSTALL_WITH_EXEC' " + "variable.") + endif() + endif() endif() endforeach() diff --git a/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake index b26c6c7..c745828 100644 --- a/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake @@ -13,6 +13,6 @@ set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so") set(EXPECTED_FILE_4_NAME "Debuginfo") set(EXPECTED_FILE_4_COMPONENT "applications-debuginfo") -set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*") +set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*") set(EXPECTED_FILE_5 "libs-DebugInfoPackage.rpm") -set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*") +set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*") diff --git a/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake b/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake index f1b6738..71457d4 100644 --- a/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake +++ b/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake @@ -8,6 +8,10 @@ endif() set(CMAKE_BUILD_TYPE Debug) +# for rpm packages execute flag must be set for shared libs if debuginfo +# packages are generated +set(CPACK_RPM_INSTALL_WITH_EXEC TRUE) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp" "int test_lib();\n") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp" diff --git a/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/ExpectedFiles.cmake index 974df22..3fb0534 100644 --- a/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/ExpectedFiles.cmake @@ -12,6 +12,6 @@ set(EXPECTED_FILE_3 "extra_slash_in_path*-libs.rpm") set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so") set(EXPECTED_FILE_4_COMPONENT "applications-debuginfo") -set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*") +set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*") set(EXPECTED_FILE_5_COMPONENT "libs-debuginfo") -set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*") +set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*") diff --git a/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/test.cmake b/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/test.cmake index 4fd1e81..7cee188 100644 --- a/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/test.cmake +++ b/Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/test.cmake @@ -8,6 +8,10 @@ endif() set(CMAKE_BUILD_TYPE Debug) +# for rpm packages execute flag must be set for shared libs if debuginfo +# packages are generated +set(CPACK_RPM_INSTALL_WITH_EXEC TRUE) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp" "int test_lib();\n") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp" diff --git a/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake index 8170d39..936e4ed 100644 --- a/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake @@ -12,19 +12,19 @@ if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid" OR RunCMake_SUBTEST_SUFFIX STREQUAL set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so") set(EXPECTED_FILE_4_COMPONENT "debuginfo") - set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp${whitespaces_}/src/src_1/test_lib.cpp.*") + set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component" OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_no_debuginfo") set(EXPECTED_FILES_COUNT "2") set(EXPECTED_FILE_1 "single_debuginfo-0*-applications.rpm") set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/test_prog") set(EXPECTED_FILE_2 "single_debuginfo-applications-debuginfo*.rpm") - set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*") + set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_main" OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_components") set(EXPECTED_FILES_COUNT "2") set(EXPECTED_FILE_1 "single_debuginfo-0*.rpm") set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/test_prog") set(EXPECTED_FILE_2 "single_debuginfo-debuginfo*.rpm") - set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*") + set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*") endif() -- cgit v0.12