Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable openssf compiler options #8998

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .github/dockerfiles/Dockerfile.64-bit
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,30 @@ RUN cd /buildroot && tar -xzf ./otp.tar.gz
WORKDIR /buildroot/otp/

ENV CFLAGS="-O2 -g -Werror -DwxSTC_DISABLE_MACRO_DEPRECATIONS=1"
ENV CFLAGS="${CFLAGS} -Wall -Wformat -Wformat=2 -Wno-conversion -Wimplicit-fallthrough \
-Werror=format-security -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS \
-fstack-clash-protection -fstack-protector-strong -Wtrampolines \
-fcf-protection=full -fexceptions -fno-strict-overflow -fno-delete-null-pointer-checks \
-D_GLIBCXX_ASSERTIONS"
## OpenSSF recommended CFLAGS, skipped are:
## -Wconversion -Wextra -Wsign-conversion - As we have way too many of these warnings
## -fstrict-flex-arrays=3 -Wbidi-chars=any - As gcc 11 does not support it
## -mbranch-protection=standard - Only on arm
## -Werror=implicit -Wincompatible-pointer-types -Wint-conversion - As these do not work on c++ code
ENV SKIPPED_OSSF_CFLAGS="-Wconversion -mbranch-protection=standard \
-Wextra -Werror=implicit -Werror=incompatible-pointer-types -Werror=int-conversion \
-Wsign-conversion"
ENV LDFLAGS="-Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -Wl,--no-copy-dt-needed-entries"
## OpenSSF recommended LDFLAGS, skipped are:
## -Wl,-z,nodlopen - as opening drivers/nifs needs this
## -fPIE - not needed with gcc 11
## -fPIC -shared - only needed for .so files
ENV SKIPPED_OSSF_LDFLAGS="-Wl,-z,nodlopen -fPIE -fPIC -shared"

## Configure (if not cached), check that no application are disabled and then make
RUN if [ ! -f Makefile ]; then \
touch README.md && \
./configure --prefix="/Erlang ∅⊤℞" && \
./configure --prefix="/Erlang ∅⊤℞" --enable-pie && \
if cat lib/*/CONF_INFO || cat lib/*/SKIP || cat lib/SKIP-APPLICATIONS; then exit 1; fi && \
find . -type f -newer README.md | xargs tar --transform 's:^./:otp/:' -cf ../otp_cache.tar; \
fi && \
Expand All @@ -26,6 +45,7 @@ RUN if [ ! -f Makefile ]; then \

## Disable -Werror as testcases do not compile with it on
ENV CFLAGS="-O2 -g"
ENV LDFLAGS=""

## Update init.sh with correct env vars
RUN echo "export MAKEFLAGS=$MAKEFLAGS" > /buildroot/env.sh && \
Expand Down
88 changes: 88 additions & 0 deletions .github/scripts/ossf-sarif-generator.es
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env escript

%% This script takes a json string as argument and checks that all the compiler flags defined by the OSSF
%% are used.

main([CompilerFlagsJson]) ->
io:format(standard_error,"~p",[os:env()]),
CFLAGS = proplists:get_value(cflags, erlang:system_info(compile_info)) ++ " " ++ os:getenv("SKIPPED_OSSF_CFLAGS"),
LDFLAGS = proplists:get_value(ldflags, erlang:system_info(compile_info)) ++ " " ++ os:getenv("SKIPPED_OSSF_LDFLAGS"),
{gnuc, {Vsn, _, _} } = erlang:system_info(c_compiler_used),
#{ ~"options" := #{ ~"recommended" := Opts } } = json:decode(unicode:characters_to_binary(CompilerFlagsJson)),
io:format(standard_error, ~s'CFLAGS="~ts"~nLDFLAGS="~ts"~n',[CFLAGS, LDFLAGS]),
Missing = [Opt || Opt <- Opts, check_option(Opt, string:split(CFLAGS, " ", all), string:split(LDFLAGS, " ", all), Vsn)],
io:format("~ts~n",[sarif(Missing)]),
ok.
check_option(#{ ~"requires" := #{ ~"gcc" := GccVsn }, ~"opt" := Opt }, CFLAGS, _LDFLAGS, CurrentGccVsn) ->
io:format(standard_error, "Looking for ~ts...",[Opt]),
case binary_to_integer(hd(string:split(GccVsn, "."))) > CurrentGccVsn of
true -> io:format(standard_error, "skipped!~n",[]), false;
false ->
check_for_flags(Opt, CFLAGS)
end;
check_option(#{ ~"requires" := #{ ~"binutils" := _ }, ~"opt" := Opt }, _CFLAGS, LDFLAGS, _CurrentGccVsn) ->
io:format(standard_error, "Looking for ~ts...",[Opt]),
check_for_flags(Opt, LDFLAGS);
check_option(#{ ~"requires" := #{ ~"libstdc++" := _ }, ~"opt" := Opt }, _CFLAGS, LDFLAGS, _CurrentGccVsn) ->
io:format(standard_error, "Looking for ~ts...",[Opt]),
check_for_flags(Opt, LDFLAGS);
check_option(#{ ~"requires" := Tool, ~"opt" := Opt }, _CFLAGS, _LDFLAGS, _CurrentGccVsn) ->
io:format(standard_error, "~ts not implemented yet using ~p!~n",[Opt, Tool]),
true.

check_for_flags(Flag, Flags) ->
case lists:any(fun(O) -> lists:search(fun(A) -> string:equal(string:trim(O), string:trim(A)) end, Flags) =:= false end, string:split(Flag, " ", all) ) of
true -> io:format(standard_error, "missing!~n",[]), true;
false -> io:format(standard_error, "found!~n",[]), false
end.

sarif(Missing) ->
Zip = lists:zip(lists:seq(1,length(Missing)), Missing),
json:encode(
#{ ~"version" => ~"2.1.0",
~"$schema" => ~"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
~"runs" =>
[ #{
~"tool" =>
#{ ~"driver" =>
#{ ~"informationUri" => ~"https://github.com/erlang/otp/.github/workflow/ossf-scanner",
~"name" => ~"ossf-scanner",
~"rules" =>
[ #{ ~"id" => base64:encode(erlang:md5(Opt)),
~"name" => ~"MissingCompilerFlag",
~"shortDescription" =>
#{ ~"text" => <<"Missing CFLAGS ", Opt/binary>> },
~"helpUri" => ~"https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++",
~"fullDescription" =>
#{
~"text" => <<Desc/binary,"\nA OSSF C/C++ compiler hardening flag is missing from the tests. "
"Please check https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++ for details.">>
}
}
|| {_Id, #{ ~"desc" := Desc, ~"opt" := Opt }} <- Zip],
~"version" => ~"1.0"
}
},
~"artifacts" =>
[ #{
~"location" => #{
~"uri" => ~".github/docker/Dockerfile.64-bit"
},
~"length" => -1
}
],
~"results" =>
[ #{
~"ruleId" => base64:encode(erlang:md5(Opt)),
~"ruleIndex" => Id,
~"level" => ~"warning",
~"message" => #{ ~"text" => <<"Missing CFLAGS ", Opt/binary>> },
~"locations" =>
[ #{ ~"physicalLocation" =>
#{ ~"artifactLocation" =>
#{ ~"uri" => ~".github/docker/Dockerfile.64-bit" }
}
} ]
} || {Id, #{ ~"opt" := Opt }} <- Zip]
} ]
}).
63 changes: 63 additions & 0 deletions .github/workflows/ossf-compiler-flags-scanner.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
## This workflow continually scan the master branch to make sure that
## the correct compiler flags are used when testing Erlang/OTP on github.

name: Open Source Security Foundation

on:
workflow_dispatch:
schedule:
- cron: 0 1 * * *

permissions:
# Required to upload SARIF file to CodeQL.
# See: https://github.com/github/codeql-action/issues/2117
actions: read
# Require writing security events to upload SARIF file to security tab
security-events: write
# Only need to read contents
contents: read

jobs:
schedule-scan:
runs-on: ubuntu-latest
if: github.repository == 'erlang/otp'
steps:
- uses: actions/[email protected]
- name: Create initial pre-release tar
run: .github/scripts/init-pre-release.sh otp_src.tar.gz
- uses: actions/[email protected]
with:
repository: ossf/wg-best-practices-os-developers
sparse-checkout: docs/Compiler-Hardening-Guides/compiler-options-scraper
path: ossf

- name: Setup compiler options scraper
run: |
pip3 install -r ossf/docs/Compiler-Hardening-Guides/compiler-options-scraper/requirements.txt
python3 ossf/docs/Compiler-Hardening-Guides/compiler-options-scraper/main.py
cat compiler-options.json

- uses: ./.github/actions/build-base-image
with:
BASE_BRANCH: master
BUILD_IMAGE: true

- name: Run compiler flag comparison
run: |
docker run -v `pwd`/.github/scripts:/github --entrypoint "" otp \
bash -c "/github/ossf-sarif-generator.es '$(cat compiler-options.json)'" > results.sarif

- name: "Upload artifact"
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4 # v4.4.3
with:
name: SARIF file
path: results.sarif

# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
if: ${{ !cancelled() }}
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif

4 changes: 4 additions & 0 deletions erts/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,10 @@
'-Waddress-of-packed-member'') */
#undef HAVE_GCC_DIAG_IGNORE_WADDRESS_OF_PACKED_MEMBER

/* define if compiler support _Pragma('GCC diagnostic ignored
'-Wformat-nonliteral'') */
#undef HAVE_GCC_DIAG_IGNORE_WFORMAT_NONLITERAL

/* Define to 1 if you have a good `getaddrinfo' function. */
#undef HAVE_GETADDRINFO

Expand Down
34 changes: 31 additions & 3 deletions erts/configure
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,6 @@ PROFILE_COMPILER
USE_PGO
XCRUN
LLVM_PROFDATA
WERRORFLAGS
WFLAGS
DEBUG_FLAGS
ERTS_CONFIG_H_IDIR
Expand Down Expand Up @@ -3663,6 +3662,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu











Expand Down Expand Up @@ -8302,7 +8306,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext




## Check if we can do profile guided optimization of beam_emu

{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -fprofile-generate -Werror..." >&5
Expand Down Expand Up @@ -26895,10 +26898,35 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="$saved_CFLAGS"

saved_CFLAGS="$CFLAGS"
CFLAGS="-Werror $CFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */

int
main (void)
{
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
_Pragma("GCC diagnostic pop")

;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :

printf "%s\n" "#define HAVE_GCC_DIAG_IGNORE_WFORMAT_NONLITERAL 1" >>confdefs.h

fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="$saved_CFLAGS"



if test "x$GCC" = xyes; then
CFLAGS="$WERRORFLAGS $CFLAGS"
CFLAGS="$WERRORFLAGS $CFLAGS"
fi


Expand Down
25 changes: 13 additions & 12 deletions erts/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,7 @@ m4_include([otp.m4])

LM_PRECIOUS_VARS

dnl We check if -Werror was given on command line and if so
dnl we disable it for the configure and only use it when
dnl actually building erts
no_werror_CFLAGS=$(echo " $CFLAGS " | sed 's/ -Werror / /g')
if test "X $CFLAGS " != "X$no_werror_CFLAGS"; then
CFLAGS="$no_werror_CFLAGS"
WERRORFLAGS=-Werror
fi
ERL_PUSH_WERROR

dnl How to set srcdir absolute is taken from the GNU Emacs distribution
#### Make srcdir absolute, if it isn't already. It's important to
Expand Down Expand Up @@ -630,7 +623,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[
dnl DEBUG_FLAGS is obsolete (I hope)
AC_SUBST(DEBUG_FLAGS)
AC_SUBST(WFLAGS)
AC_SUBST(WERRORFLAGS)

## Check if we can do profile guided optimization of beam_emu
LM_CHECK_RUN_CFLAG([-fprofile-generate -Werror],[PROFILE_GENERATE])
Expand Down Expand Up @@ -3621,14 +3613,23 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[_Pragma("GCC diagnostic push")
define if compiler support _Pragma('GCC diagnostic ignored '-Waddress-of-packed-member''))],[])
CFLAGS="$saved_CFLAGS"

dnl ----------------------------------------------------------------------
dnl Check for GCC diagnostic ignored "-Wformat-nonliteral"
dnl ----------------------------------------------------------------------
saved_CFLAGS="$CFLAGS"
CFLAGS="-Werror $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
_Pragma("GCC diagnostic pop")
]])],[AC_DEFINE(HAVE_GCC_DIAG_IGNORE_WFORMAT_NONLITERAL,1,
define if compiler support _Pragma('GCC diagnostic ignored '-Wformat-nonliteral''))],[])
CFLAGS="$saved_CFLAGS"

dnl ----------------------------------------------------------------------
dnl Enable any -Werror flags
dnl ----------------------------------------------------------------------

if test "x$GCC" = xyes; then
CFLAGS="$WERRORFLAGS $CFLAGS"
fi
ERL_POP_WERROR

dnl ----------------------------------------------------------------------
dnl Enable build determinism flag
Expand Down
4 changes: 2 additions & 2 deletions erts/emulator/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ $(OBJDIR)/%.o: nifs/$(ERLANG_OSTYPE)/%.c
# included before any other directives, including other #includes.
#
ASMJIT_FLAGS=-DASMJIT_EMBED=1 -DASMJIT_NO_BUILDER=1 -DASMJIT_NO_DEPRECATED=1 -DASMJIT_STATIC=1 -DASMJIT_NO_FOREIGN=1

ASMJIT_CXXFLAGS=$(filter-out -Wformat -Wformat=2, $(CXXFLAGS))
ASMJIT_PCH_OBJ=$(TTF_DIR)/asmjit/asmjit.hpp.gch
ASMJIT_PCH_SRC=$(TTF_DIR)/asmjit/asmjit.hpp

Expand All @@ -960,7 +960,7 @@ $(OBJDIR)/%.o: beam/jit/$(JIT_ARCH)/%.cpp beam/jit/$(JIT_ARCH)/beam_asm.hpp $(AS

$(OBJDIR)/asmjit/%.o: asmjit/%.cpp $(ASMJIT_PCH_OBJ) $(dir $@)
$(V_CXX) $(ASMJIT_FLAGS) $(INCLUDES) \
$(subst -O2, $(GEN_OPT_FLGS), $(CXXFLAGS)) \
$(subst -O2, $(GEN_OPT_FLGS), $(ASMJIT_CXXFLAGS)) \
-include $(ASMJIT_PCH_SRC) -c $< -o $@

## The dependency on erl_bif_info.c is in order to trigger a rebuild when
Expand Down
6 changes: 6 additions & 0 deletions erts/emulator/beam/beam_bp.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,15 @@ erts_bp_match_functions(BpFunctions* f, ErtsCodeMFA *mfa, int specified)
case 3:
if (ci->mfa.arity != mfa->arity)
continue;
ERTS_FALLTHROUGH();
case 2:
if (ci->mfa.function != mfa->function)
continue;
ERTS_FALLTHROUGH();
case 1:
if (ci->mfa.module != mfa->module)
continue;
ERTS_FALLTHROUGH();
case 0:
break;
}
Expand Down Expand Up @@ -259,12 +262,15 @@ erts_bp_match_export(BpFunctions* f, ErtsCodeMFA *mfa, int specified)
case 3:
if (mfa->arity != ep->info.mfa.arity)
continue;
ERTS_FALLTHROUGH();
case 2:
if (mfa->function != ep->info.mfa.function)
continue;
ERTS_FALLTHROUGH();
case 1:
if (mfa->module != ep->info.mfa.module)
continue;
ERTS_FALLTHROUGH();
case 0:
break;
default:
Expand Down
Loading
Loading