Skip to content

Commit 33c0181

Browse files
authored
Build/security: Try FORTIFY_SOURCE (#3575)
Add a new build-time cmake cache variable: FORTIFY_SOURCE Default to empty, but can be set to 1, 2, or 3, corresponding to setting the _FORTIFY_SOURCE macro available in recent versions of clang and gcc. (I'm not sure exactly which minimum compiler version is needed for each fortification level, except that for level 3, gcc must be 12+.) Fortification involves replacing several "unsafe" memory-related functions such as memcpy, memset, strcpy, etc, with special versions that do bounds checking, aided by some compiler smarts for understanding the likely bounds of different buffers. If I understand correctly, at level 2 it can figure out bounds of constant-sized arrays, and at level 3 it can figure out certain dynamic cases as well. There are two use cases for this: 1. For our own CI, this is yet another bit of static and dynamic anslysis to enable (currently, just in the gcc12 test) to possibly catch bugs. 2. Users who are building OIIO to deploy it in security-sensitive environment may wish to build with some fortification level enabled to help prevent certain memory errors or security issues, understanding that it may slightly impact performance.
1 parent 5dd9fee commit 33c0181

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ jobs:
271271
PUGIXML_VERSION=master
272272
USE_OPENVDB=0
273273
WEBP_VERSION=master
274+
OIIO_CMAKE_FLAGS="-DFORTIFY_SOURCE=2"
274275
# The installed OpenVDB has a TLS conflict with Python 3.8
275276
- desc: clang14 C++20 avx2 exr3.1 ocio2.1
276277
nametag: linux-clang14

src/cmake/compiler.cmake

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,29 @@ if (SANITIZE AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG))
432432
endif ()
433433

434434

435+
###########################################################################
436+
# Fortification and hardening options
437+
#
438+
# In modern gcc and clang, FORTIFY_SOURCE provides buffer overflow checks
439+
# (with some compiler-assisted deduction of buffer lengths) for the following
440+
# functions: memcpy, mempcpy, memmove, memset, strcpy, stpcpy, strncpy,
441+
# strcat, strncat, sprintf, vsprintf, snprintf, vsnprintf, gets.
442+
#
443+
# We try to avoid these unsafe functions anyway, but it's good to have the
444+
# extra protection, at least as an extra set of checks during CI. Some users
445+
# may also wish to enable it at some level if they are deploying it in a
446+
# security-sensitive environment. FORTIFY_SOURCE=3 may have minor performance
447+
# impact, though FORTIFY_SOURCE=2 should not have a measurable effect on
448+
# performance versus not doing any fortification. All fortification levels are
449+
# not available in all compilers.
450+
451+
set (FORTIFY_SOURCE "0" CACHE STRING "Turn on Fortification level (0, 1, 2, 3)")
452+
if (FORTIFY_SOURCE AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG))
453+
message (STATUS "Compiling with _FORTIFY_SOURCE=${FORTIFY_SOURCE}")
454+
add_compile_options (-D_FORTIFY_SOURCE=${FORTIFY_SOURCE})
455+
endif ()
456+
457+
435458
###########################################################################
436459
# clang-tidy options
437460
#

0 commit comments

Comments
 (0)