Skip to content

Commit

Permalink
[librpsecure] New consolidated security library.
Browse files Browse the repository at this point in the history
The os-secure files from rpcli and rp-download have been consolidated
into a single library. seccomp-debug.h has also been moved here and
converted into a .c file with a public interface in the .h file.

rpcli and rp-download can now call rp_secure_enable() with an OS-specific
parameter. A struct is provided that makes the parameter type-safe.

NOTE: syscall_wl (seccomp syscall whitelist) can't be NULL-terminated,
since syscall 0 is valid on most architectures. On x86, it's read().
Hence, we're specifying an explicit array size.

Also moved the Win32 security options and integrity level files here.
Updated Win32 code for this change.

integrity_level.c: Removed the pthread_once() usage for the Windows Vista
check, since we're not linking to librpthreads. The worst that could happen
is both threads set isVista to the same value.

[cmake] Adjusted security options:
- USE_SECCOMP: Moved from cmake/options.cmake to librpsecure/CMakeLists.txt.
- ENABLE_SECCOMP_DEBUG: Added to librpsecure/CMakeLists.txt. Replaces
  the hard-coded SECCOMP_DEBUG in seccomp-debug.h.

[svrplus] Removed the libwin32common dependency. It was only used for the
Windows security options, and that's now handled by librpsecure.

[tests] Updated gtest_init.cpp to use librpsecure. Link all test suites to
librpsecure instead of libwin32common.
- TODO: seccomp() on Linux, pledge() on OpenBSD.
  • Loading branch information
GerbilSoft committed Feb 27, 2020
1 parent fb62b29 commit 6234bd0
Show file tree
Hide file tree
Showing 43 changed files with 588 additions and 666 deletions.
2 changes: 0 additions & 2 deletions cmake/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ ENDIF(WIN32 AND MSVC)
# Linux security options.
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
OPTION(INSTALL_APPARMOR "Install AppArmor profiles." ON)
OPTION(USE_SECCOMP "Use libseccomp filters in rp-download and rpcli." ON)
ELSE(CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(INSTALL_APPARMOR OFF)
SET(USE_SECCOMP OFF)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/config.version.h.in" "${CMAKE_CURREN
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/stdboolx.h.in" "${CMAKE_CURRENT_BINARY_DIR}/stdboolx.h")

# Source Code subdirectories.
ADD_SUBDIRECTORY(librpsecure)
ADD_SUBDIRECTORY(libi18n)
ADD_SUBDIRECTORY(librpthreads)
ADD_SUBDIRECTORY(libcachecommon)
Expand Down
5 changes: 1 addition & 4 deletions src/libcachecommon/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ ADD_EXECUTABLE(FilterCacheKeyTest
../../librpbase/tests/gtest_init.cpp
FilterCacheKeyTest.cpp
)
IF(WIN32)
TARGET_LINK_LIBRARIES(FilterCacheKeyTest PRIVATE win32common)
ENDIF(WIN32)
TARGET_LINK_LIBRARIES(FilterCacheKeyTest PRIVATE rpbase cachecommon)
TARGET_LINK_LIBRARIES(FilterCacheKeyTest PRIVATE rpsecure rpbase cachecommon)
TARGET_LINK_LIBRARIES(FilterCacheKeyTest PRIVATE gtest)
DO_SPLIT_DEBUG(FilterCacheKeyTest)
SET_WINDOWS_SUBSYSTEM(FilterCacheKeyTest CONSOLE)
Expand Down
4 changes: 4 additions & 0 deletions src/libromdata/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,10 @@ TARGET_INCLUDE_DIRECTORIES(romdata
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}> # top-level
)
IF(WIN32)
# librpsecure: integrity_level.h
TARGET_LINK_LIBRARIES(romdata PRIVATE rpsecure)

# Windows SDK libraries.
TARGET_LINK_LIBRARIES(romdata PRIVATE advapi32)
IF(MSVC)
TARGET_LINK_LIBRARIES(romdata PRIVATE delayimp)
Expand Down
4 changes: 3 additions & 1 deletion src/libromdata/img/ExecRpDownload_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

// Windows includes.
#include "libwin32common/RpWin32_sdk.h"
#include "libwin32common/integrity_level.h"
#include "librpbase/TextFuncs_wchar.hpp"

// librpsecure
#include "librpsecure/win32/integrity_level.h"

// C++ includes.
#include <string>
using std::string;
Expand Down
13 changes: 5 additions & 8 deletions src/libromdata/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ IF(ENABLE_DECRYPTION)
../../librpbase/tests/gtest_init.cpp
CtrKeyScramblerTest.cpp
)
TARGET_LINK_LIBRARIES(CtrKeyScramblerTest PRIVATE romdata rpbase)
TARGET_LINK_LIBRARIES(CtrKeyScramblerTest PRIVATE rpsecure romdata rpbase)
TARGET_LINK_LIBRARIES(CtrKeyScramblerTest PRIVATE gtest)
DO_SPLIT_DEBUG(CtrKeyScramblerTest)
SET_WINDOWS_SUBSYSTEM(CtrKeyScramblerTest CONSOLE)
Expand All @@ -24,7 +24,7 @@ ADD_EXECUTABLE(GcnFstPrint
disc/FstPrint.hpp
disc/GcnFstPrint.cpp
)
TARGET_LINK_LIBRARIES(GcnFstPrint PRIVATE romdata rpbase)
TARGET_LINK_LIBRARIES(GcnFstPrint PRIVATE rpsecure romdata rpbase)
IF(ENABLE_NLS)
TARGET_LINK_LIBRARIES(GcnFstPrint PRIVATE i18n)
ENDIF(ENABLE_NLS)
Expand All @@ -44,7 +44,7 @@ ADD_EXECUTABLE(GcnFstTest
disc/FstPrint.hpp
disc/GcnFstTest.cpp
)
TARGET_LINK_LIBRARIES(GcnFstTest PRIVATE romdata rpbase)
TARGET_LINK_LIBRARIES(GcnFstTest PRIVATE rpsecure romdata rpbase)
IF(ENABLE_NLS)
TARGET_LINK_LIBRARIES(GcnFstTest PRIVATE i18n)
ENDIF(ENABLE_NLS)
Expand Down Expand Up @@ -82,10 +82,7 @@ ADD_EXECUTABLE(ImageDecoderTest
../../librpbase/tests/gtest_init.cpp
img/ImageDecoderTest.cpp
)
IF(WIN32)
TARGET_LINK_LIBRARIES(ImageDecoderTest PRIVATE win32common)
ENDIF(WIN32)
TARGET_LINK_LIBRARIES(ImageDecoderTest PRIVATE romdata rpbase)
TARGET_LINK_LIBRARIES(ImageDecoderTest PRIVATE rpsecure romdata rpbase)
TARGET_LINK_LIBRARIES(ImageDecoderTest PRIVATE gtest ${ZLIB_LIBRARY})
TARGET_INCLUDE_DIRECTORIES(ImageDecoderTest PRIVATE ${ZLIB_INCLUDE_DIRS})
TARGET_COMPILE_DEFINITIONS(ImageDecoderTest PRIVATE ${ZLIB_DEFINITIONS})
Expand Down Expand Up @@ -145,7 +142,7 @@ ADD_EXECUTABLE(SuperMagicDriveTest
utils/SuperMagicDriveTest.cpp
utils/SuperMagicDriveTest_data.hpp
)
TARGET_LINK_LIBRARIES(SuperMagicDriveTest PRIVATE romdata rpbase)
TARGET_LINK_LIBRARIES(SuperMagicDriveTest PRIVATE rpsecure romdata rpbase)
TARGET_LINK_LIBRARIES(SuperMagicDriveTest PRIVATE gtest)
TARGET_LINK_LIBRARIES(SuperMagicDriveTest PRIVATE ${ZLIB_LIBRARY})
TARGET_INCLUDE_DIRECTORIES(SuperMagicDriveTest PRIVATE ${ZLIB_INCLUDE_DIRS})
Expand Down
11 changes: 8 additions & 3 deletions src/libromdata/tests/disc/GcnFstPrint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ using std::ostream;
using std::ostringstream;
using std::string;

// librpsecure
#include "librpsecure/os-secure.h"

#ifdef _WIN32
# include "libwin32common/RpWin32_sdk.h"
# include "libwin32common/secoptions.h"
# include <io.h>
# include "librpbase/TextFuncs.hpp"
# include "librpbase/TextFuncs_wchar.hpp"
Expand All @@ -41,9 +43,12 @@ using std::u16string;

int RP_C_API main(int argc, char *argv[])
{
// Set OS-specific security options.
// TODO: Non-Windows syscall stuff.
#ifdef _WIN32
// Set Win32 security options.
rp_secoptions_init(TRUE);
rp_secure_param_t param;
param.bHighSec = FALSE;
rp_secure_enable(param);
#endif /* _WIN32 */

// Set the C and C++ locales.
Expand Down
18 changes: 4 additions & 14 deletions src/librpbase/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ ADD_EXECUTABLE(RpImageLoaderTest
img/RpImageLoaderTest.cpp
img/RpPngFormatTest.cpp
)
IF(WIN32)
TARGET_LINK_LIBRARIES(RpImageLoaderTest PRIVATE win32common)
ENDIF(WIN32)
TARGET_LINK_LIBRARIES(RpImageLoaderTest PRIVATE rpbase)
TARGET_LINK_LIBRARIES(RpImageLoaderTest PRIVATE rpsecure rpbase)
TARGET_LINK_LIBRARIES(RpImageLoaderTest PRIVATE gtest ${ZLIB_LIBRARY})
TARGET_INCLUDE_DIRECTORIES(RpImageLoaderTest PRIVATE ${ZLIB_INCLUDE_DIRS})
TARGET_COMPILE_DEFINITIONS(RpImageLoaderTest PRIVATE ${ZLIB_DEFINITIONS})
Expand Down Expand Up @@ -63,10 +60,9 @@ IF(ENABLE_DECRYPTION)
gtest_init.cpp
AesCipherTest.cpp
)
TARGET_LINK_LIBRARIES(AesCipherTest PRIVATE rpbase)
TARGET_LINK_LIBRARIES(AesCipherTest PRIVATE rpsecure rpbase)
TARGET_LINK_LIBRARIES(AesCipherTest PRIVATE gtest)
IF(WIN32)
TARGET_LINK_LIBRARIES(AesCipherTest PRIVATE win32common)
TARGET_LINK_LIBRARIES(AesCipherTest PRIVATE advapi32)
ENDIF(WIN32)
IF(NETTLE_LIBRARY)
Expand All @@ -85,10 +81,7 @@ ADD_EXECUTABLE(TextFuncsTest
TextFuncsTest.cpp
TextFuncsTest_data.hpp
)
IF(WIN32)
TARGET_LINK_LIBRARIES(TextFuncsTest PRIVATE win32common)
ENDIF(WIN32)
TARGET_LINK_LIBRARIES(TextFuncsTest PRIVATE rpbase)
TARGET_LINK_LIBRARIES(TextFuncsTest PRIVATE rpsecure rpbase)
TARGET_LINK_LIBRARIES(TextFuncsTest PRIVATE gtest)
DO_SPLIT_DEBUG(TextFuncsTest)
SET_WINDOWS_SUBSYSTEM(TextFuncsTest CONSOLE)
Expand All @@ -101,10 +94,7 @@ ADD_EXECUTABLE(ByteswapTest
ByteswapTest.cpp
ByteswapTest_data.hpp
)
IF(WIN32)
TARGET_LINK_LIBRARIES(ByteswapTest PRIVATE win32common)
ENDIF(WIN32)
TARGET_LINK_LIBRARIES(ByteswapTest PRIVATE rpbase)
TARGET_LINK_LIBRARIES(ByteswapTest PRIVATE rpsecure rpbase)
TARGET_LINK_LIBRARIES(ByteswapTest PRIVATE gtest)
DO_SPLIT_DEBUG(ByteswapTest)
SET_WINDOWS_SUBSYSTEM(ByteswapTest CONSOLE)
Expand Down
14 changes: 9 additions & 5 deletions src/librpbase/tests/gtest_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ using std::locale;
#include "librpbase/common.h"
#include "tcharx.h"

#ifdef _WIN32
#include "libwin32common/secoptions.h"
// librpsecure
#include "librpsecure/os-secure.h"

#ifdef _WIN32
// rp_image backend registration.
#include "librptexture/img/RpGdiplusBackend.hpp"
#include "librptexture/img/rp_image.hpp"
Expand All @@ -32,14 +33,17 @@ extern "C" int gtest_main(int argc, TCHAR *argv[]);

int RP_C_API _tmain(int argc, TCHAR *argv[])
{
// Set OS-specific security options.
// TODO: Non-Windows syscall stuff.
#ifdef _WIN32
// Set Win32 security options.
rp_secoptions_init(FALSE);
rp_secure_param_t param;
param.bHighSec = FALSE;
rp_secure_enable(param);

// Register RpGdiplusBackend.
// TODO: Static initializer somewhere?
rp_image::setBackendCreatorFn(RpGdiplusBackend::creator_fn);
#endif
#endif /* _WIN32 */

// TODO: setenv() wrapper in config.librpbase.h.in?
#if defined(HAVE_SETENV)
Expand Down
79 changes: 79 additions & 0 deletions src/librpsecure/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Security functionality.
PROJECT(librpsecure)

IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
OPTION(USE_SECCOMP "Use libseccomp filters in rp-download and rpcli." ON)
OPTION(ENABLE_SECCOMP_DEBUG "Enable libseccomp debugging." OFF)
ELSE()
SET(USE_SECCOMP OFF CACHE INTERNAL "Use libseccomp filters in rp-download and rpcli." FORCE)
SET(ENABLE_SECCOMP_DEBUG OFF CACHE INTERNAL "Enable libseccomp debugging." FORCE)
ENDIF()

IF(WIN32)
SET(librpsecure_SRCS
win32/integrity_level.c
win32/secoptions.c
)
SET(librpsecure_H
os-secure.h
win32/integrity_level.h
win32/secoptions.h
win32/secoptions_win8.h
)
SET(librpsecure_OS_SRCS os-secure_win32.c)
ELSEIF(UNIX AND NOT APPLE)
# Check for system security functionality.
IF(USE_SECCOMP)
# Linux: Use seccomp().
FIND_PACKAGE(Seccomp REQUIRED)
IF(SECCOMP_FOUND)
SET(librpsecure_OS_SRCS os-secure_linux.c)
IF(ENABLE_SECCOMP_DEBUG)
SET(librpsecure_OS_SRCS ${librpsecure_OS_SRCS} seccomp-debug.c)
SET(librpsecure_OS_H ${librpsecure_OS_H} seccomp-debug.h)
ENDIF(ENABLE_SECCOMP_DEBUG)
SET(HAVE_SECCOMP 1)
ENDIF(SECCOMP_FOUND)
ELSE()
# OpenBSD: Use pledge()/tame().
INCLUDE(CheckOpenBSDPledge)
CHECK_OPENBSD_PLEDGE()
IF(HAVE_PLEDGE OR HAVE_TAME)
SET(librpsecure_OS_SRCS os-secure_openbsd.c)
ENDIF()
ENDIF()
ENDIF()

IF(NOT librpsecure_OS_SRCS)
# TODO: Add support for other systems.
SET(librpsecure_OS_SRCS os-secure_dummy.c)
ENDIF(NOT librpsecure_OS_SRCS)

# Write the config.h file.
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/config.librpsecure.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.librpsecure.h")

######################
# Build the library. #
######################

ADD_LIBRARY(rpsecure STATIC
${librpsecure_SRCS}
${librpsecure_H}
${librpsecure_OS_SRCS}
${librpsecure_OS_H}
)
INCLUDE(SetMSVCDebugPath)
SET_MSVC_DEBUG_PATH(rpsecure)
# Exclude from ALL builds.
SET_TARGET_PROPERTIES(rpsecure PROPERTIES EXCLUDE_FROM_ALL TRUE)
IF(USE_SECCOMP AND SECCOMP_FOUND)
TARGET_LINK_LIBRARIES(rpsecure PUBLIC Seccomp::seccomp)
ENDIF(USE_SECCOMP AND SECCOMP_FOUND)

TARGET_INCLUDE_DIRECTORIES(rpsecure
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> # librpsecure
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # librpsecure
PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..> # src
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/..> # src
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
)
27 changes: 27 additions & 0 deletions src/librpsecure/config.librpsecure.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/***************************************************************************
* ROM Properties Page shell extension. (librpsecure) *
* config.librpsecure.h.in: librpsecure configuration. (source file) *
* *
* Copyright (c) 2016-2020 by David Korth. *
* SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/

#ifndef __ROMPROPERTIES_LIBRPSECURE_CONFIG_H__
#define __ROMPROPERTIES_LIBRPSECURE_CONFIG_H__

/* Define to 1 if you have the OpenBSD 5.8 `tame` function. */
#cmakedefine HAVE_TAME 1

/* Define to 1 if you have the OpenBSD 5.9+ `pledge` function. */
#cmakedefine HAVE_PLEDGE 1

/* Define to 1 if you have the OpenBSD 6.3+ `pledge` function with `execpromises`. */
#cmakedefine HAVE_PLEDGE_EXECPROMISES 1

/* Define to 1 if you have the Linux `seccomp` library. */
#cmakedefine HAVE_SECCOMP 1

/* Define to 1 to enable seccomp debugging. */
#cmakedefine ENABLE_SECCOMP_DEBUG 1

#endif /* __ROMPROPERTIES_LIBRPSECURE_CONFIG_H__ */
76 changes: 76 additions & 0 deletions src/librpsecure/os-secure.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/***************************************************************************
* ROM Properties Page shell extension. (librpsecure) *
* os-secure.h: OS security functions. *
* *
* Copyright (c) 2016-2020 by David Korth. *
* SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/

#ifndef __ROMPROPERTIES_LIBRPSECURE_OS_SECURE_H__
#define __ROMPROPERTIES_LIBRPSECURE_OS_SECURE_H__

#include "config.librpsecure.h"

#ifdef _WIN32
# include <windows.h>
#else /* !_WIN32 */
# include <unistd.h>
# ifdef HAVE_SECCOMP
# include <seccomp.h>
# elif HAVE_TAME
# include <sys/tame.h>
# endif
#endif /* _WIN32 */


#ifdef __cplusplus
extern "C" {
#endif

/**
* Reduce the process integrity level to Low.
* (Windows only; no-op on other platforms.)
* @return 0 on success; negative POSIX error code on error.
*/
#ifdef _WIN32
int rp_secure_reduce_integrity(void);
#else /* !_WIN32 */
static inline int rp_secure_reduce_integrity(void)
{
return 0;
}
#endif /* _WIN32 */

/**
* OS-specific security parameter.
*
* NOTE: This should be sizeof(void*) or less so it can be
* passed by value.
*/
typedef struct _rp_secure_param_t {
#if defined(_WIN32)
BOOL bHighSec; // High security mode
#elif defined(HAVE_SECCOMP)
const int *syscall_wl; // Array of allowed syscalls. (-1 terminated)
#elif defined(HAVE_PLEDGE)
const char *promises; // pledge() promises
#elif defined(HAVE_TAME)
int tame_flags; // tame() flags
#else
# warning rp_secure_enable() not implemented for this OS
int dummy; // to prevent having an empty struct
#endif
} rp_secure_param_t;

/**
* Enable OS-specific security functionality.
* @param param OS-specific parameter.
* @return 0 on success; negative POSIX error code on error.
*/
int rp_secure_enable(rp_secure_param_t param);

#ifdef __cplusplus
}
#endif

#endif /* __ROMPROPERTIES_LIBRPSECURE_OS_SECURE_H__ */
Loading

0 comments on commit 6234bd0

Please sign in to comment.