diff --git a/.github/workflows/buildsCI.yaml b/.github/workflows/buildsCI.yaml index bc46e5bed6..78d4f98436 100644 --- a/.github/workflows/buildsCI.yaml +++ b/.github/workflows/buildsCI.yaml @@ -215,6 +215,48 @@ jobs: run: | python3 unit-tests/run-unit-tests.py --no-color --debug --stdout --not-live --context "dds windows" ${{env.WIN_BUILD_DIR}}/Release +#-------------------------------------------------------------------------------- + Win_SH_Py_DDS_SEC: # Windows, Shared, Python, Tools, DDS, additional security checks + runs-on: windows-2019 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.8.1' + + - name: Enable Long Paths + shell: powershell + run: | + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force + + - name: Check_API + shell: bash + run: | + cd scripts + ./api_check.sh + cd .. + + - name: PreBuild + shell: bash + run: | + mkdir ${{env.WIN_BUILD_DIR}} + python3 -m pip install numpy + + - name: Configure CMake + shell: bash + run: | + LRS_SRC_DIR=$(pwd) + cd ${{env.WIN_BUILD_DIR}} + cmake ${LRS_SRC_DIR} -G "Visual Studio 16 2019" -DBUILD_SHARED_LIBS=true -DBUILD_EXAMPLES=false -DBUILD_TOOLS=true -DBUILD_UNIT_TESTS=false -DCHECK_FOR_UPDATES=false -DBUILD_WITH_DDS=true -DPYTHON_EXECUTABLE=${{env.PYTHON_PATH}} -DBUILD_PYTHON_BINDINGS=true -DENABLE_SECURITY_FLAGS=true + + - name: Build + # Build your program with the given configuration + shell: bash + run: | + cd ${{env.WIN_BUILD_DIR}} + cmake --build . --config ${{env.LRS_RUN_CONFIG}} -- -m + #-------------------------------------------------------------------------------- Win_SH_Py_RSUSB_Csharp: # Windows, Shared, Python, RSUSB backend, C# bindings @@ -394,6 +436,55 @@ jobs: python3 unit-tests/run-unit-tests.py --no-color --debug --stdout --not-live --context "dds linux" --tag dds + #-------------------------------------------------------------------------------- + U20_ST_Py_DDS_RSUSB_SEC: # Ubuntu 2020, Static, Python, DDS, RSUSB, additional security checks + runs-on: ubuntu-20.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + + - name: Prebuild + shell: bash + run: | + sudo apt-get update; + sudo apt-get install -qq build-essential xorg-dev libgl1-mesa-dev libglu1-mesa-dev libglew-dev libglm-dev; + sudo apt-get install -qq libusb-1.0-0-dev; + sudo apt-get install -qq libgtk-3-dev; + sudo apt-get install libglfw3-dev libglfw3; + # We force compiling with GCC 7 because the default installed GCC 9 compiled with LTO and gives an internal compiler error + sudo apt-get install gcc-7 g++-7; + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-7; + python3 -m pip install numpy + + - name: Check_API + shell: bash + run: | + cd scripts + ./api_check.sh + ./pr_check.sh + cd .. + mkdir build + + - name: Build + # Note: we force RSUSB because, on Linux, the context creation will fail on GHA: + # (backend-v4l2.cpp:555) Cannot access /sys/class/video4linux) + # And, well, we don't need any specific platform for DDS! + shell: bash + run: | + cd build + cmake .. -DCMAKE_BUILD_TYPE=${{env.LRS_RUN_CONFIG}} -DBUILD_SHARED_LIBS=false -DBUILD_EXAMPLES=false -DBUILD_TOOLS=false -DBUILD_UNIT_TESTS=false -DCHECK_FOR_UPDATES=false -DBUILD_WITH_DDS=true -DBUILD_PYTHON_BINDINGS=true -DPYTHON_EXECUTABLE=$(which python3) -DFORCE_RSUSB_BACKEND=true -DENABLE_SECURITY_FLAGS=true + cmake --build . -- -j4 + + - name: Client for realsense2-all + shell: bash + run: | + mkdir build/rs-all-client + cd build/rs-all-client + cmake ../../.github/workflows/rs-all-client -DBUILD_WITH_DDS=ON -DFORCE_RSUSB_BACKEND=ON + cmake --build . -- -j4 + ./rs-all-client + + #-------------------------------------------------------------------------------- U22_U24_SH_Py_DDS_CI: # Ubuntu, Shared, Python, DDS, LibCI without executables runs-on: ${{ matrix.os }} diff --git a/CMake/external_fastdds.cmake b/CMake/external_fastdds.cmake index 856e0dbfc7..59e16290b9 100644 --- a/CMake/external_fastdds.cmake +++ b/CMake/external_fastdds.cmake @@ -67,7 +67,10 @@ function(get_fastdds) message(CHECK_PASS "Done") endfunction() + +pop_security_flags() + # Trigger the FastDDS build get_fastdds() - +push_security_flags() diff --git a/CMake/external_foonathan_memory.cmake b/CMake/external_foonathan_memory.cmake index f6c4938267..de91069005 100644 --- a/CMake/external_foonathan_memory.cmake +++ b/CMake/external_foonathan_memory.cmake @@ -41,4 +41,8 @@ function(get_foonathan_memory) endfunction() +pop_security_flags() + get_foonathan_memory() + +push_security_flags() diff --git a/CMake/external_libcurl.cmake b/CMake/external_libcurl.cmake index ac967e1cd2..61f804814b 100644 --- a/CMake/external_libcurl.cmake +++ b/CMake/external_libcurl.cmake @@ -1,4 +1,7 @@ if(CHECK_FOR_UPDATES) + + pop_security_flags() # remove security flags + include(ExternalProject) message(STATUS "Building libcurl enabled") @@ -60,4 +63,5 @@ if(CHECK_FOR_UPDATES) endif() endif() + push_security_flags() endif() #CHECK_FOR_UPDATES diff --git a/CMake/lrs_options.cmake b/CMake/lrs_options.cmake index cc2b21de13..02ca70796b 100644 --- a/CMake/lrs_options.cmake +++ b/CMake/lrs_options.cmake @@ -47,4 +47,5 @@ endif() option(BUILD_PC_STITCHING "Build pointcloud-stitching example" OFF) option(BUILD_WITH_DDS "Access camera devices through DDS topics (requires CMake 3.16.3)" OFF) option(BUILD_RS2_ALL "Build realsense2-all static bundle containing all realsense libraries (with BUILD_SHARED_LIBS=OFF)" ON) +option(ENABLE_SECURITY_FLAGS "Enable additional compiler security flags to enhance the build's security" OFF) diff --git a/CMake/security_flags_helper_functions.cmake b/CMake/security_flags_helper_functions.cmake new file mode 100644 index 0000000000..5dc52e16e2 --- /dev/null +++ b/CMake/security_flags_helper_functions.cmake @@ -0,0 +1,20 @@ +macro(push_security_flags) # remove security flags + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SECURITY_COMPILER_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SECURITY_COMPILER_FLAGS}") +endmacro() + +macro(pop_security_flags) # append security flags + string(REPLACE "${SECURITY_COMPILER_FLAGS}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REPLACE "${SECURITY_COMPILER_FLAGS}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +endmacro() + +macro(set_security_flags_for_executable) # replace flag fPIC (Position-Independent Code) with fPIE (Position-Independent Executable) + string(REPLACE "-fPIC" "-fPIE" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REPLACE "-fPIC" "-fPIE" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +endmacro() + +macro(unset_security_flags_for_executable) # replace flag fPIE (Position-Independent Executable) with fPIC (Position-Independent Code) + string(REPLACE "-fPIE" "-fPIC" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REPLACE "-fPIE" "-fPIC" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +endmacro() + diff --git a/CMake/unix_config.cmake b/CMake/unix_config.cmake index 711434c2ef..c038809d51 100644 --- a/CMake/unix_config.cmake +++ b/CMake/unix_config.cmake @@ -47,6 +47,49 @@ macro(os_set_flags) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") endif() + set(SECURITY_COMPILER_FLAGS "") + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND ENABLE_SECURITY_FLAGS) + # Due to security reasons we need to add the following flags for additional security: + # Debug & Release: + # -Wformat: Checks for format string vulnerabilities. + # -Wformat-security: Ensures format strings are not vulnerable to attacks. + # -fPIC: Generates position-independent code during the compilation phase. + # -fPIE: Generates position-independent executables during the compilation phase. + # -D_FORTIFY_SOURCE=2: Adds extra checks for buffer overflows. + # -fstack-protector: Adds stack protection to detect buffer overflows. + + # Release only + # -Werror: Treats all warnings as errors. + # -Werror=format-security: Treats format security warnings as errors. + # -z noexecstack: Marks the stack as non-executable to prevent certain types of attacks. + # -Wl,-z,relro,-z,now: Enables read-only relocations and immediate binding for security. + # -fstack-protector-strong: Provides stronger stack protection than -fstack-protector. + + # Linker flags + # -pie: Produces position-independent executables during the linking phase. + + # see https://readthedocs.intel.com/SecureCodingStandards/2023.Q2.0/compiler/c-cpp/ for more details + + set(SECURITY_COMPILER_FLAGS "-Wformat -Wformat-security -fPIC -fstack-protector -Wno-error=stringop-overflow") + + string(FIND "${CMAKE_CXX_FLAGS}" "-D_FORTIFY_SOURCE" _index) + if (${_index} EQUAL -1) # Define D_FORTIFY_SOURCE if undefined + set(SECURITY_COMPILER_FLAGS "${SECURITY_COMPILER_FLAGS} -D_FORTIFY_SOURCE=2") + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Configuring for Debug build") + else() # Release, RelWithDebInfo, or multi configuration generator is being used (aka not specifing build type, or building with VS) + message(STATUS "Configuring for Release build") + set(SECURITY_COMPILER_FLAGS "${SECURITY_COMPILER_FLAGS} -Werror -z noexecstack -Wl,-z,relro,-z,now -fstack-protector-strong") + endif() + + push_security_flags() + + set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -pie") + + endif() + if(APPLE) set(FORCE_RSUSB_BACKEND ON) endif() diff --git a/CMake/windows_config.cmake b/CMake/windows_config.cmake index 3bd808b07a..8f87a59942 100644 --- a/CMake/windows_config.cmake +++ b/CMake/windows_config.cmake @@ -40,6 +40,41 @@ macro(os_set_flags) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") + set(SECURITY_COMPILER_FLAGS "") + if (ENABLE_SECURITY_FLAGS) + # Due to security reasons we need to add the following flags for additional security: + # Debug & Release: + # /Gy: Enables function-level linking to reduce executable size. + # /DYNAMICBASE: Enables Address Space Layout Randomization (ASLR) to improve security. + # /GS: Enables buffer security checks to prevent buffer overflows. + + # Release only: + # /WX: Treats all warnings as errors. + # /sdl: Enables additional security checks. + + # Release only linker flags: + # /LTCG (/GL): Enables Link Time Code Generation to improve performance. + # /NXCOMPAT: Enables Data Execution Prevention (DEP) to prevent code execution in data areas. + + # see https://readthedocs.intel.com/SecureCodingStandards/2023.Q2.0/compiler/c-cpp/ for more details + + set(SECURITY_COMPILER_FLAGS "/Gy /DYNAMICBASE /GS /wd4101") + + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Configuring for Debug build") + else() # Release, RelWithDebInfo, or multi configuration generator is being used (aka not specifing build type, or building with VS) + message(STATUS "Configuring for Release build") + set(SECURITY_COMPILER_FLAGS "${SECURITY_COMPILER_FLAGS} /WX /sdl") + endif() + + push_security_flags() + + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} /INCREMENTAL:NO /LTCG /NXCOMPAT") # ignoring '/INCREMENTAL' due to '/LTCG' specification + endif() + + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /wd4819") set(LRS_TRY_USE_AVX true) add_definitions(-D_UNICODE) diff --git a/CMakeLists.txt b/CMakeLists.txt index 467c844b09..24cfb79587 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,9 @@ endif() list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/CMake) +# include security flags helper functions +include(CMake/security_flags_helper_functions.cmake) + # include librealsense general configuration include(CMake/global_config.cmake) @@ -60,7 +63,7 @@ target_link_libraries( ${LRS_TARGET} PUBLIC rsutils ) if(BUILD_WITH_DDS) if (CMAKE_SYSTEM MATCHES "Windows" OR CMAKE_SYSTEM MATCHES "Linux") - + message(STATUS "Building with FastDDS") include(CMake/external_foonathan_memory.cmake) include(CMake/external_fastdds.cmake) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 652656e589..b43469404d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1) # View the makefile commands during build #set(CMAKE_VERBOSE_MAKEFILE on) +set_security_flags_for_executable() # examples are executables so we want position indepandent executables and not libraries + set( DEPENDENCIES ${LRS_TARGET} ) if(BUILD_GRAPHICAL_EXAMPLES) include(${CMAKE_SOURCE_DIR}/CMake/opengl_config.cmake) @@ -40,3 +42,5 @@ add_subdirectory(record-playback) add_subdirectory(motion) add_subdirectory(gl) add_subdirectory(hdr) + +unset_security_flags_for_executable() diff --git a/include/librealsense2/hpp/rs_export.hpp b/include/librealsense2/hpp/rs_export.hpp index 6e7d097791..337d34bc61 100644 --- a/include/librealsense2/hpp/rs_export.hpp +++ b/include/librealsense2/hpp/rs_export.hpp @@ -81,7 +81,7 @@ namespace rs2 bool use_normals = get_option(OPTION_PLY_NORMALS) != 0; const auto verts = p.get_vertices(); const auto texcoords = p.get_texture_coordinates(); - const uint8_t* texture_data; + const uint8_t* texture_data = nullptr; if (use_texcoords) // texture might be on the gpu, get pointer to data before for-loop to avoid repeated access texture_data = reinterpret_cast(color.get_data()); std::vector new_verts; diff --git a/src/hid-sensor.cpp b/src/hid-sensor.cpp index 03f831aeeb..f62ba07a8f 100644 --- a/src/hid-sensor.cpp +++ b/src/hid-sensor.cpp @@ -145,7 +145,7 @@ void hid_sensor::close() std::lock_guard< std::mutex > lock( _configure_lock ); _configured_profiles.clear(); _is_configured_stream.clear(); - _is_configured_stream.resize( RS2_STREAM_COUNT ); + _is_configured_stream.assign(RS2_STREAM_COUNT, false); } _is_opened = false; if( Is< librealsense::global_time_interface >( _owner ) ) diff --git a/src/hid/hid-device.cpp b/src/hid/hid-device.cpp index aaa3a18a40..01d79ad3fd 100644 --- a/src/hid/hid-device.cpp +++ b/src/hid/hid-device.cpp @@ -334,7 +334,7 @@ namespace librealsense //we want to change the sensitivity values only in gyro, for FW version >= 5.16 if( featureReport.reportId == REPORT_ID_GYROMETER_3D && _realsense_hid_report_actual_size == sizeof( REALSENSE_HID_REPORT ) ) - featureReport.sensitivity = sensitivity; + featureReport.sensitivity = static_cast(sensitivity); res = dev->control_transfer(USB_REQUEST_CODE_SET, diff --git a/src/uvc/uvc-device.cpp b/src/uvc/uvc-device.cpp index 84897e0163..a23615ae74 100644 --- a/src/uvc/uvc-device.cpp +++ b/src/uvc/uvc-device.cpp @@ -177,7 +177,7 @@ namespace librealsense switch(state) { case D0: - _messenger = _usb_device->open(_info.mi); + _messenger = _usb_device->open(static_cast(_info.mi)); if (_messenger) { try{ @@ -654,7 +654,7 @@ namespace librealsense void rs_uvc_device::listen_to_interrupts() { - auto ctrl_interface = _usb_device->get_interface(_info.mi); + auto ctrl_interface = _usb_device->get_interface(static_cast(_info.mi)); if (!ctrl_interface) return; auto iep = ctrl_interface->first_endpoint(RS2_USB_ENDPOINT_DIRECTION_READ, RS2_USB_ENDPOINT_INTERRUPT); @@ -856,7 +856,7 @@ namespace librealsense req, probe ? (UVC_VS_PROBE_CONTROL << 8) : (UVC_VS_COMMIT_CONTROL << 8), ctrl->bInterfaceNumber, // When requestType is directed to an interface, the driver automatically passes the interface number in the low byte of index - buf, len, transferred, 0); + buf, static_cast(len), transferred, 0); } while (sts != RS2_USB_STATUS_SUCCESS && retries++ < 5); } }, [this](){ return !_messenger; }); diff --git a/src/uvc/uvc-streamer.cpp b/src/uvc/uvc-streamer.cpp index 3e1c7aa487..01ccf9998e 100644 --- a/src/uvc/uvc-streamer.cpp +++ b/src/uvc/uvc-streamer.cpp @@ -28,7 +28,7 @@ namespace librealsense _action_dispatcher.start(); - _watchdog_timeout = (1000.0 / _context.profile.fps) * 10; + _watchdog_timeout = static_cast(((1000.0 / _context.profile.fps) * 10)); init(); } diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index c70314062e..c28e66c84d 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -1,9 +1,11 @@ string(REPLACE ${PROJECT_SOURCE_DIR}/ "" _rel_path ${CMAKE_CURRENT_LIST_DIR}) -include(CMake/external_json.cmake) add_subdirectory( "${CMAKE_CURRENT_LIST_DIR}/rsutils" ) +pop_security_flags() # remove security flags for third party, as we cannot guarantee their security enforcment + +include(CMake/external_json.cmake) # Add additional include directories to allow file to include rosbag headers include(${_rel_path}/realsense-file/config.cmake) @@ -18,3 +20,5 @@ if( BUILD_WITH_DDS ) add_subdirectory( "${CMAKE_CURRENT_LIST_DIR}/realdds" ) endif() +# restore security flags +push_security_flags() diff --git a/third-party/rsutils/src/json.cpp b/third-party/rsutils/src/json.cpp index 81653ada1d..6428bc7003 100644 --- a/third-party/rsutils/src/json.cpp +++ b/third-party/rsutils/src/json.cpp @@ -411,7 +411,7 @@ class serializer { dump( *i, pretty_print_width, ensure_ascii, indent_step, new_indent ); _o.put( ',' ); - if( need_to_indent || pretty_print_width && _line_width > pretty_print_width ) + if( need_to_indent || (pretty_print_width && _line_width > pretty_print_width )) { newline(); _o.write( _indent_string.c_str(), new_indent ); @@ -1100,7 +1100,7 @@ class serializer } }; - JSON_ASSERT(byte < utf8d.size()); + JSON_ASSERT(static_cast(byte) < utf8d.size()); const std::uint8_t type = utf8d[byte]; codep = (state != UTF8_ACCEPT) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 99807a4602..7098757b98 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1) # View the makefile commands during build #set(CMAKE_VERBOSE_MAKEFILE on) +set_security_flags_for_executable() # tools are executables so we want position indepandent executables and not libraries + list( APPEND DEPENDENCIES ${LRS_TARGET} tclap ) if(BUILD_TOOLS) @@ -45,3 +47,5 @@ if(BUILD_EXAMPLES) endif() endif() endif() + +unset_security_flags_for_executable() diff --git a/wrappers/csharp/Intel.RealSense/Devices/AutoCalibratedDevice.cs b/wrappers/csharp/Intel.RealSense/Devices/AutoCalibratedDevice.cs index 4233d36e75..4b198cda57 100644 --- a/wrappers/csharp/Intel.RealSense/Devices/AutoCalibratedDevice.cs +++ b/wrappers/csharp/Intel.RealSense/Devices/AutoCalibratedDevice.cs @@ -11,7 +11,7 @@ public class AutoCalibratedDevice : CalibratedDevice internal AutoCalibratedDevice(IntPtr dev) : base(dev) { } - public static AutoCalibratedDevice FromDevice(Device dev) + public static new AutoCalibratedDevice FromDevice(Device dev) { object error; if (NativeMethods.rs2_is_device_extendable_to(dev.Handle, Extension.AutoCalibratedDevice, out error) == 0)